- •ЛР 1. Операторы и выражения Delphi
- •Оператор присваивания
- •Арифметические операторы
- •Оператор конкатенации строк
- •Логические операторы
- •Операторы поразрядного сдвига
- •Операторы отношения
- •Операторы множеств
- •Составной оператор begin..end
- •Условный оператор if..then..else
- •Оператор-селектор case
- •Оператор перехода goto
- •Оператор with..do
- •Организация циклов
- •Цикл с параметром for..do
- •Инструкция in в цикле for..do
- •Цикл с предусловием while..do
- •Цикл с постусловием repeat..until
- •Вложенные циклы
- •Операторы break и continue
- •ЗАДАНИЕ
- •Вариант 1.
- •Вариант 2
- •Вариант 3
- •Вариант 4
- •Вариант 5
- •Вариант 6
- •Вариант 7
- •Вариант 8
- •Вариант 9
- •Вариант 10
- •Вариант 11
- •Вариант 12
- •ЛР 2. Структурные типы
- •Множества
- •Записи
- •Вариантные поля
- •Усовершенствованная запись
- •Массивы
- •Объявление массива
- •Обращение к ячейкам массива
- •Динамический массив
- •ЗАДАНИЕ
- •Вариант 1
- •Вариант 2
- •Вариант 3
- •Вариант 4
- •Вариант 5
- •Вариант 6
- •Вариант 7
- •Вариант 8
- •Вариант 9
- •Вариант 10
- •Вариант 11
- •Вариант 12
- •ЛР 3. Объекты и классы
- •Проектирование класса
- •Управление жизненным циклом объекта
- •Опережающее объявление класса
- •Ограничение видимости членов класса
- •Свойства объекта
- •Особенности объявления методов
- •Поля класса и методы класса
- •Иерархия наследования
- •Полиморфизм
- •ЗАДАНИЕ
- •Вариант 1
- •Вариант 2
- •Вариант 3
- •Вариант 4
- •ЛР4. Опорные классы VCL
- •Класс TObject
- •Класс TPersistent
- •Основа компонента, класс TComponent
- •Владение компонентом
- •Класс TControl
- •Принадлежность к родительскому контейнеру
- •Размещение и размеры элемента управления
- •События, связанные с изменением размеров
- •Выравнивание элемента управления в контейнере
- •Видимость и активность элемента управления
- •Задание
- •Вариант 1
- •Вариант 2
- •Вариант 3
- •Вариант 4
- •Вариант5
- •Совет
- •ЛР5. Обработка клавиатурных событий и событий мышки
- •Щелчки кнопками мыши
- •Перемещение указателя мыши
- •Вращение колесика мыши
- •Операция перетаскивания drag and drop
- •Обработка событий клавиатуры
- •Задание
- •Вариант 1
- •Вариант 2
- •Вариант 3
- •Вариант 4
- •Вариант 5
- •ЛР 6. Классы потоков данных
- •Прототип потоков данных, класс TStream
- •Потоки с дескриптором, класс THandleStream
- •Файловый поток данных, класс TFileStream
- •Пример работы с файловым потоком данных
- •Задание
- •Вариант 1.
- •Вариант 2.
- •Вариант 3.
- •Вариант 4.
- •Вариант 5.
Языки программирования
время копирования автоматически проверяется корректность операций чтения/записи и при возникновении ошибки вызывается исключительная ситуация.
Потоки с дескриптором, класс 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
СКФУ Кафедра компьютерной безопасности