Главная страница

реферат Простые операторы. Характеристика форм.docx. Лр операторы и выражения Delphi


Скачать 1.3 Mb.
НазваниеЛр операторы и выражения Delphi
Дата17.04.2023
Размер1.3 Mb.
Формат файлаdoc
Имя файлареферат Простые операторы. Характеристика форм.docx.doc
ТипПрограмма
#1067638
страница25 из 26
1   ...   18   19   20   21   22   23   24   25   26

Прототип потоков данных, класс TStream


Абстрактный класс TStream описан в модуле Classes. Он определяет концепцию построения всех своих наследников и определяет общие для всех принципы чтения и записи в поток данных.

Класс вооружен всего парой свойств:

property Size: : Int64;

property Position : Int64;

Размер потока данных Size измеряется в байтах. Попытка редактировать значение свойства в родительском классе не даст никаких результатов, но такая возможность реализована в некоторых потомках TStream. Свойство Position возвращает текущую позицию курсора внутри потока во время операций чтения или записи.

За изменение позиции курсора внутри потока отвечает метод

function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;

Здесь параметр Offset определяет новую позицию внутри потока, а параметр

Origin уточняет правила определения позиции.

type TSeekOrigin = (soBeginning, //отступ Offset байт от начала потока soCurrent, //сместиться на Offset от текущего положения soEnd); //отступ (Offset<=0) байт от конца потока

Для чтения данных из потока объявлен метод

function Read(var Buffer; Count: Longint): Longint;

Процесс записи поддерживает функция

function Write(const Buffer; Count: Longint): Longint;

Методы Read() и Write() низкоуровневые, поэтому для осуществления операций ввода/вывода я рекомендую обращаться к более совершенным процедурам:

procedure ReadBuffer(var Buffer; Count: Longint);

procedure WriteBuffer(const Buffer; Count: Longint);

Данные процедуры представляют собой надстройки над методами Read() и Write(), их ключевая особенность в том, что при невозможности считать/записать указанное в аргументе Count число байтов немедленно генерируется исключительная ситуация: EReadError или EWriteError. Благодаря этому разработчик получает возможность контролировать корректность поведения своей программы.

Для копирования данных в поток из другого потока предназначен метод

function CopyFrom(Source: TStream; Count: Longint): Longint;

Здесь Source поток-источник, а Count число копируемых байтов. При необходимости полностью скопировать поток в параметр Count передается аргумент 0. Функция возвращает размер скопированного потока. Так как для выполнения операции задействуются методы ReadBuffer() и WriteBuffer() во
время копирования автоматически проверяется корректность операций чтения/записи и при возникновении ошибки вызывается исключительная ситуация.

Потоки с дескриптором, класс 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

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


Таблица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;
Листинг 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 do begin

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

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

end; fs.Destroy;

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

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

Воспользуемся вновь полученными знаниями и разработаем небольшую утилиту, позволяющую просматривать содержимое любого файла в шестнадцатеричном формате. Для этого нам потребуется создать новый проект и разместить на поверхности формы 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 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;
end; end;
Щелчок по пункту меню активирует диалог открытия файла. В диалоговом окне пользователь выбирает для просмотра любой файл. Данные из файла считываются в массив, состоящий из 16 ячеек. Затем, после нумерации строк и несложного форматирования, текст построчно передается в компонент Memo1. Операция считывания повторяется вновь до тех пор, пока не доберется до конца файла.

Программа почти готова. Нам осталось написать 3 строки кода в обработчике события OnShow() формы проекта (листинг 6.5).


Листинг 6.5. Настройка многострочного редактора и диалога открытия файла




procedure TForm1.FormShow(Sender: TObject);

begin

Memo1.Font.Name:='Courier New'; Memo1.ReadOnly:=True; OpenDialog1.Filter:='Все файлы|*.*';

end;
Вам осталось откомпилировать проект и попробовать его в работе на каком-нибудь небольшом файле (рис. 6.2).

docshapegroup542




1   ...   18   19   20   21   22   23   24   25   26


написать администратору сайта