реферат Простые операторы. Характеристика форм.docx. Лр операторы и выражения Delphi
Скачать 1.3 Mb.
|
Прототип потоков данных, класс 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.Константырежимаоткрытияфайла
Таблица6.2.Константыопределенияправдоступа
В листинге 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 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 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). |