Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ООП / ООП_Лекции.doc
Скачиваний:
50
Добавлен:
08.06.2015
Размер:
1.03 Mб
Скачать

8. Работа с потоками

Обычные программы, написанные на языке Pascal, управляют файлами несколькими способами, такими как, например, использо­вание стандартных функций и процедур языка Pascal для работы с файлами DOS и Windows. Однако Delphi представляет новую концепцию — поток (stream) и использует ее достаточно интенсивно: класс TStream и его наиболее общие производные — классы TReader и TWriter, класс TPersistent и класс TComponent.

Классы потоковDelphi

Если вы не знакомы с потоками как понятием программирования, необходимо уяснить основной смысл потоков в природе. Каждый поток имеет определенное начало и конец, и, как правило, можно определить текущую позицию относительно начала и конца потока. Кроме того, при возвращении к той же самой позиции в потоке, отсутствует гарантия возврата к «той же воде, тем же водорослям или рыбе».

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

Модуль Classes в VCL определяет абстрактный класс, названный TStream, и несколько классов прямых потомков.

• TFileStream определяет поток, управляющий файлом на диске (файлом, существующим на локальном или сетевом диске), используя имя файла. Данное свойство наследуется из класса THandleStream.

• THandleStream определяет поток, управляющий файлом на диске, используя дескриптор handle файла Windows.

• TMemoryStream определяет поток, управляющий последовательностью байтов в памяти, наследуемый из TCustomMemoryStream.

• TResourceStream определяет поток, который управляет последовательностью байтов в памяти, а также обеспечивает возможности преобразования ресурса. Он наследуется из

TCustomMemoryStream.

• TBlobStream определяет поток, обеспечивающий простой доступ к полям данных BLOB.

• TVirtualStream определяет редко документированный класс, используемый интер­фейсами инструментов Delphi Tool Services (или ToolsAPI).

• TOleStreamObject (представленный в Delphi 3) определяет поток для чтения и записи информации через интерфейс для работы с потоками, предоставляемый в OLE.

• TStringStream (представленный в Delphi 3) обеспечивает простой способ использования потока для длинной строки.

• TWinSocketStream (представленный в Delphi 3) обеспечивает поддержку потоков, подключаемых через соединительные разъемы.

Класс TStream определяет два свойства: размер size и позицию Position, являющиеся общими для всех классов потоков. Если воспринимать поток как подобие фрагмента провода или строки, получается полезная рабочая аналогия. Любой определенный фрагмент провода, веревки или строки имеет размер (определенную длину), и обычно материал обрабатывается в определенной позиции в пределах длины. Единицы измерения позиции и длины (дюймы, сантиметры, или нечто другое) может меняться от одного материала к другому, но смысл остается тем же.

Точно так же все объекты потока Delphi имеют особый размер, и приходится определять позицию внутри потока, где требуется либо чтение, либо запись информации. Чтение и запись байтов в THandleStream дает не такой результат, как чтение и запись полей в базе данных BLOB, но в обоих случаях вам нет необходимости знать намного больше, чем размер потока и текущую позицию в потоке для чтения или записи данных. Это одно из преимуществ использо­вания потоков. Базисный интерфейс остается тем же самым при управлении файлом на диске, полем BLOB или длинной последовательностью байтов в памяти.

В дополнение к свойствам Size и Position, класс TStream также определяет несколько важных методов, большинство из которых являются виртуальными и абстрактными. (Другими словами, класс TStream не определяет то, что делают эти методы; следовательно, порожденные классы сами отвечают за выполнение.) Некоторые из этих методов важны только в контексте чтения или записи компонентов внутри потока (например, ReadComponent и WriteComponent), но некоторые из этих методов также полезны и в других контекстах. Вот объявление класса TStream:

TStream = class(TObject)

public

// чтение и запись буфера

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

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

procedure ReadBuffer(var Buffer; Count: Longint);

procedure WriteBuffer(const Buffer; Count: Longint); // перемещение на заданную позицию function Seek(Offset: Longint; Origin: Word): Longint;virtual; abstract; // копирование потока

function CopyFrom(Source: TStream; Count: Longint): Longint; // чтение или запись компонента

function ReadComponent(Instance: TComponent): TComponent;

function ReadComponentRes(Instance: TComponent): TComponent;

procedure WriteComponent(Instance: TComponent);

procedure WriteComponentRes(

const ResName: string; Instance: TComponent);

procedure WriteDescendent(Instance, Ancestor: TComponent);

procedure WriteDescendentRes(const ResName: string; Instance, Ancestor: TComponent);

procedure ReadResHeader;

// свойства

property Position: Longint read GetPosition write SetPosition;

property Size: Longint read GetSize;

end;

Очевидно, что нет смысла пробовать создавать объект TStream, так как этот класс не определяет способ чтения или записи данных в поток. Вместо этого класс TStream определяет стандартный интерфейс для всех классов потока. Пытаясь создать объект TStream и обратиться к методам при выполнении программы, вероятнее всего сгенерируется ошибка 102 периода выполнения, указывающая, что ваша программа вызвала абстрактную функцию, не обеспечив реализацию этой функции.

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

Соседние файлы в папке ООП