ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 10.01.2024
Просмотров: 276
Скачиваний: 1
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
СОДЕРЖАНИЕ
ЛР 1. Операторы и выражения Delphi
Управление жизненным циклом объекта
Ограничение видимости членов класса
Особенности объявления методов
Принадлежность к родительскому контейнеру
Размещение и размеры элемента управления
Видимость и активность элемента управления
ЛР5. Обработка клавиатурных событий и событий мышки
листинг программы не превысил 60 строк кода!
Еще в начале 1990-х годов в составе языка программирования Turbo Pascal 6.0 появился весьма неординарный класс TStream. В логику класса разработчики сумели вложить единую методологию для осуществления операций ввода-вывода в файлы, коммуникационные порты, массивы бинарных данных, ресурсы приложений. В результате на свет появилась удобная абстракция, которая оказалась способной описать процесс переноса битов данных от источника к приемнику. Эта абстракция нашла свое воплощение в многочисленных потомках класса TStream, которые мы станем называть потоками данных.
Поток данных способен оказать неоценимые услуги в приложениях, предназначенных для чтения (записи) данных из внешнего источника. Так класс TFileStream специализируется на файловых операциях, TMemoryStream незаменим в операциях с памятью, TStringStream предназначен для управления текстовыми строками в памяти (рис. 6.1).
Рис. 6.1. Иерархия классов 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. Пример записи данных в файловый поток
ЛР 6. Классы потоков данных
Еще в начале 1990-х годов в составе языка программирования Turbo Pascal 6.0 появился весьма неординарный класс TStream. В логику класса разработчики сумели вложить единую методологию для осуществления операций ввода-вывода в файлы, коммуникационные порты, массивы бинарных данных, ресурсы приложений. В результате на свет появилась удобная абстракция, которая оказалась способной описать процесс переноса битов данных от источника к приемнику. Эта абстракция нашла свое воплощение в многочисленных потомках класса TStream, которые мы станем называть потоками данных.
Поток данных способен оказать неоценимые услуги в приложениях, предназначенных для чтения (записи) данных из внешнего источника. Так класс TFileStream специализируется на файловых операциях, TMemoryStream незаменим в операциях с памятью, TStringStream предназначен для управления текстовыми строками в памяти (рис. 6.1).
Рис. 6.1. Иерархия классов TStream
Прототип потоков данных, класс 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. Пример записи данных в файловый поток