Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторки 1-6 по Delphi.pdf
Скачиваний:
39
Добавлен:
08.04.2015
Размер:
1.09 Mб
Скачать

Языки программирования

время копирования автоматически проверяется корректность операций чтения/записи и при возникновении ошибки вызывается исключительная ситуация.

Потоки с дескриптором, класс THandleStream

Класс THandleStream предназначен для создания потомков, способных производить чтение/запись в коммуникационный ресурс. В роли последнего могут выступать как обычный файл, так и сокет или именованный канал, главное условие в том, чтобы он обладал дескриптором коммуникационного ресурса.

property Handle: Integer; //только для чтения

Это свойство доступно только для чтения. Для того чтобы наполнить его содержанием, программист должен поработать с конструктором потока

constructor Create(AHandle: Integer);

Единственный параметр метода Create() как раз требует передачи дескриптора ресурса. Хороший пример (см. листинг 11.1) получения дескриптора в момент вызова конструктора демонстрирует прямой наследник THandleStream — класс

TFileStrem.

Файловый поток данных, класс TFileStream

Файловый поток данных специализируется на обмене информацией между программой и файлом. Всеми своими умениями файловый поток обязан своим предкам, классам TStream и THandleStream, а основная особенность TFileStream заключена в его конструкторе

constructor Create(const FileName: string; Mode: Word); overload;

constructor Create(const FileName: string; Mode: Word; Rights: Cardinal); overload;

С вызовом конструктора создается файловый объект, который ассоциируется с файлом с именем FileName. Параметр Mode описывает режим открытия файла (табл. 6.1), параметр Right — права на доступ (табл. 6.2).

 

 

Таблица 6.1. Константы режима открытия файла

 

 

 

Константа

Значени

Описание

 

е

 

 

 

 

fmCreate

$0000

Создать файл с именем FileName. Если файл с

 

 

таким именем уже существует, то он открывается с

 

 

правами для записи

 

 

 

fmOpenRead

$0001

Открыть только для чтения

fmOpenWrite

$0002

Открыть только для записи

fmOpenReadWrite

$0004

Файл одновременно доступен для чтения и записи

60

СКФУ Кафедра компьютерной безопасности

Языки программирования

 

 

Таблица 6.2. Константы определения прав доступа

 

 

 

Константа

Значени

Описание

 

е

 

 

 

 

fmShareCompat

$0000

Устаревшая константа, оставленная для обратной

 

 

совместимости с проектами для DOS

fmShareExclusive

$0010

Эксклюзивный доступ к файлу, запрещает обращение

 

 

из других процессов

fmShareDenyWrite

$0020

Другим процессам разрешено только чтение из файла

fmShareDenyRead

$0030

Другим процессам разрешена только запись в файл

fmShareDenyNone

$0040

Файл доступен для других процессов (приложений)

В листинге 6.1 представлен сокращенный код конструктора файлового потока.

Листинг 6.1. Конструктор класса TFileStream

type TFileStream = class(THandleStream) public

...

constructor TFileStream.Create(const FileName: string;

Mode: Word; Rights: Cardinal);

begin

...

if Mode = fmCreate then

{режим создания файла — получим дескриптор нового файла}

inherited Create(FileCreate(AFileName, LShareMode, Rights)); else

{режим открытия — получим дескриптор открытого файла} inherited Create(FileOpen(FileName, Mode));

end;

В зависимости от порядка доступа к файлу, указанного в параметре Mode, его дескриптор возвращают объявленные в модуле SysUtils функции FileCreate() или FileOpen(). Если по каким-либо причинам открыть (создать) файл не удалось, то конструктор генерирует исключительную ситуацию EFOpenError или

EFCreateError.

Имя файла, ассоциированного с потоком данных, доступно в свойстве property FileName: string;

Для организации операций чтения, записи и перемещения курсора по потоку используют унаследованные от THandleStream методы Read(), Write() и Seek().

Завершив работу с файловым объектом, необходимо вызвать его деструктор: destructor Destroy; override;

61

СКФУ Кафедра компьютерной безопасности

Языки программирования

Листинг 6.2 демонстрирует код, создающий двоичный файл и помещающий в него 1 Кбайт данных.

Листинг 6.2. Пример записи данных в файловый поток

var fs:TFileStream;

Buf : array [0..1023] of byte;

i :integer; begin

fs:=TFileStream.Create('c:\demo.dat', fmCreate);{создаем файл и поток} for i:=0 to SizeOf(Buf)-1 do Buf[i]:=Random(255); {заполнение буфера

случайными числами} fs.Write(Buf,SizeOf(Buf)); //запись данных в файл

fs.Destroy; {уничтожаем файловый поток} end;

Организация чтения данных из файлового потока требует учитывать текущее положение курсора чтения в потоке. Для этого нам понадобится пара свойств: Position и Size. Кроме того, размер буфера должен быть кратен размеру файла (листинг 6.3).

Листинг 6.3. Пример чтения данных из файлового потока

var fs : TFileStream;

Buf : array[0..127] of byte; begin

fs:=TFileStream.Create('c:\demo.dat', fmOpenRead);

while fs.Position<fs.Size do begin

fs.Read(Buf, SizeOf(Buf));//считываем порцию данных в буфер

//дальнейшая обработка данных в буфере Buf end;

fs.Destroy; end;

После открытия файлового потока курсор устанавливается на первом байте данных. В цикле while..do контролируется местоположения курсора — чтение осуществляется до тех пор, пока курсор не попытается уйти за пределы файлового потока.

Замечание

В составе модуля IOUtils объявлена интеллектуальная запись TFile, позволяющая создавать файл методом Create(), открывать OpenRead() и OpenWrite() и возвращать экземпляр потока TFileStream

62

СКФУ Кафедра компьютерной безопасности

Языки программирования

Пример работы с файловым потоком данных

Воспользуемся вновь полученными знаниями и разработаем небольшую утилиту, позволяющую просматривать содержимое любого файла в шестнадцатеричном формате. Для этого нам потребуется создать новый проект и разместить на поверхности формы 3 компонента:

главное меню (TMainMenu);

диалог открытия файла (TOpenDialog);

текстовый редактор (TMemo).

Дважды щелкнув по главному меню, вызовите редактор меню и создайте в нем единственный элемент "Открыть". Переименуйте этот элемент: Name=miOpen. Затем опишите обработчик события OnClick() по элементу меню так, как предложено в листинге 6.4.

Листинг 6.4. Обрабатываем данные с помощью TFileStream

procedure TfrmMain.miOpenClick(Sender: TObject); var FS :TFileStream;

LineNum :integer;

buf : Array[0..15] of byte; s :string;

begin

if OpenDialog1.Execute then begin

Memo1.Lines.BeginUpdate;

Memo1.Clear; try

FS:=TFileStream.Create(OpenDialog1.FileName,fmOpenRead);

LineNum:=0;

while FS.Position<FS.Size do begin

ZeroMemory(@buf,High(buf)+1); //обнуляем буфер FS.Read(buf,SizeOf(Buf));

S:=Format('%.6x| %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x %.2x',

[LineNum,buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7],

buf[8],buf[9],buf[10],buf[11],buf[12],buf[13],buf[14],buf[15]]);

Memo1.Lines.Add(s);

INC(LineNum,$10); end;

finally

Memo1.Lines.EndUpdate;

FS.Free; end;

63

СКФУ Кафедра компьютерной безопасности