Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции Delphi (Колосов).pdf
Скачиваний:
77
Добавлен:
11.05.2015
Размер:
2.57 Mб
Скачать

14.2. Типированные файлы

Типированный файл – это файл с прямым доступом, в котором все записи имеют одинаковую длину. Например, можно объявить типированный файл следующим образом:

Type Tz=Record Fio:String[40]; Voz:Byte; End;

Var f:file of Tz;

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

Рассмотрим дополнительные процедуры и функции для работы с типированными файлами:

Procedure Seek(var f; n:LongInt); – перемещает текущий указатель файла в начало n–й записи. Записи здесь нумеруются с нуля;

Function FileSize(var f):LongInt; – возвращает длину файла в записях; Function FilePos(var f):LongInt; – возвращает номер текущей записи;

Procedure Truncate(var f); – усекает файл с текущей позиции, т.е. отсекаются все записи, начиная с текущей записи.

Рассмотрим пример замены в любом файле одного символа на другой. Будем использовать те же компоненты, что и в предыдущем примере, только результат замены будем записывать прямо в исходный файл. Заменим, например, во всем файле маленькую букву «я» на большую «Я». Обработчик нажатия кнопки «Выполнить» будет тогда иметь следующий вид:

Procedure Button1Click(Sender:Tobject);

Var

f1:File of Char; // Определяем типированный файл с длиной

 

// одной записи в один символ

C:Char;l:longint;

 

Begin

 

 

s1:=Edit1.Text;

// Путь к текстовому файлу

AssignFile(f1,s1);

// Назначение файловых переменных

{$I-} // Отключение стандартной обработки ошибок ввода–вывода

Reset(f1);

// Открываем исходный файл на чтение

Io:=IOResult;

// Запоминаем ошибку открытия файла

{$I+} // Восстанавливаем стандартную обработку ошибок ввода–вывода If io<>0 then Begin // Проверяем наличие ошибок открытия файла

// Если есть ошибки, то выводим предупреждающее сообщение

MessageDlg('Ошибка при открытии файла '+s1, mtWarning, [mbOk], 0);

Return

End;

61

Memo1.lines.Loadfromfile(s1); // Выводим в Memo1 начальный файл

// Открываем цикл посимвольного чтения исходного файла

For l:=0 to Pred(FileSize(f1)) Do Begin Read(f1,c);

If c=’я’ then Begin c:=’Я’; seek(f1,l); Write(f1,c); End;

End;

CloseFile(f1);

Memo2.Lines.LoadFromFile(s1);

End;

14.3. Нетипированные файлы

Файлы без типа, нетипированные файлы, определяются, например оператором:

Var F:file;

Эти файлы являются файлами с прямым доступом и фиксированной длиной одного блока. Длина одного блока по умолчанию равняется 128 байтам. Приведем дополнительные процедуры и функции для работы именно с такими файлами:

Procedure ReWrite(var f:file[;ReсSize:word]); – открытие нового файла на запись, RecSize – длина одного блока в байтах;

Procedure Reset(var f:file[;RecSize:Word]); – открытие файла на чтение, RecSize – длина одного блока в байтах;

Procedure BlockRead(var f:file; var Buf; Count:Integer[;var Result:Integer]);

– чтение блоков из файла f и запись их в буфер – Buf. Count – число блоков, которые хотим прочитать, Result – число блоков, реально прочитанных;

Procedure BlockWrite(var f:file; var Buf; Count:Integer [; var Result:Integer ]); – запись блоков в файл f из буфера Buf. Count – число блоков, которые хотим записать, Result – число блоков, реально записанных в файл;

Function FileSize(var f:file):Integer; – возвращает число записанных блоков в файле f.

В качестве примера работы с нетипированными файлами приведем текст программы быстрого копирования файлов, которая может быть вызвана прямо из командной строки операционной системы:

Program CopyMy;

 

Const LBuf=65000;

// Длина буфера

Var

f1,f2:File;

// f1 – файл чтения, f2 – файл записи

s1,s2:String;

// Строки для хранения путей к файлам

Buf:Array[1..Lbuf] of byte; // Буфер io,lr,lrt,lw,lwt:integer; // Внутренние переменные

Begin

// Проверка наличия двух параметров в командной строке

62

If paramcount<2 then Begin

ShowMessage(’Обращение к программе: CopyMy f1 f2’); Halt; // Аварийный выход из программы

End;

S1:=paramstr(1); // Из командной строки извлекаем путь к файлу чтения S2:=paramstr(2); // Из командной строки извлекаем путь к файлу записи

Assignfile(f1,s1); {$I-}

Reset(f1,1); // Открываем файл f1 на чтение с длиной блока в 1 байт Io:=IOResult;// Запоминаем ошибку открытия файла f1

{$I+}

if io<>0 then Begin ShowMessage(’Файла ’+s1+’ нет!’); Halt;

End;

 

 

Assignfile(f2,s2);

 

 

ReWrite(f2,1);

// Открываем файл f2 на запись с длиной блока в 1 байт

While not Eof(f1) do Begin // Открываем цикл переписи файла f1

lr:=lbuf;

 

 

BlockRead(f1,Buf,lr,lrt);

// Читаем из f1 lr блоков

BlockWrite(f2,Buf,lrt,lwt);

// Записываем в f2 lrt блоков

If lrt<>lwt then Begin // Проверяем правильность записи

ShowMessege(’Ошибка при переписи файла’); Halt;

End;

End;

CloseFile(f1);// Закрываем файлы

CloseFile(f2);

End.

Обращение к такой программе из командной строки, например, может быть таким:

CopyMy A:\p1.pas C:\my\p1.pas

15. РАБОТА С ФАЙЛАМИ И КАТАЛОГАМИ

Для работы с файловой системой используются следующие функции и процедуры:

Function DiskSize(Drive: Byte): Int64; – получение размера диска в байтах.

Параметр Drive определяет номер дисковода: 0 – текущий дисковод, 1 – A, 2 – B и т.д.;

Function DiskFree(Drive: Byte): Int64; – получение размера свободной области на диске;

Procedure ChDir(const S: string);overload; – смена текущей директории,

например ChDir(’C:\My\’);

Procedure RmDir(const S: string);overload; – удаление пустой директории;

63

Procedure MkDir(const S: string); overload; – создание новой поддиректории;

Procedure GetDir(D: Byte; var S: string); – получение текущей директории на устройстве D;

Procedure Rename(var F; Newname: string); – переименование файла,

связанного с файловой переменной F, в файл с именем Newname;

Procedure Erase(var F); – удаление закрытого файла, связанного с переменной F;

Function DirectoryExists(const Directory: string): Boolean; – проверка существования директории. Если она есть, то функция возвращает – True;

Function FileExists(const FileName: string): Boolean; – проверка наличия на диске файла с именем FileName;

Function FileGetAttr(const FileName: string): Integer; – получение атрибутов файла FileName;

Function FileAge(const FileName: string): Integer; – получение в сжатом виде даты создания файла для файла FileName;

Function FileDateToDateTime(FileDate: Integer): TDateTime; – перевод сжатой информации о дате создания файла в стандартный формат даты– времени. Для перевода его в строку следует использовать функцию DateToStr;

Function FileSearch(const Name, DirList: string): string; – поиск файла

Name в списке каталогов DirList;

Function FindFirst(const Path: string; Attr: Integer; var F: TSearchRec): Integer; – функция первого поиска файла в заданной директории и с заданным атрибутом, результат поиска помещается в запись F, она возвращает 0, если файл найден, иначе – код ошибки;

Function FindNext(var F: TSearchRec): Integer; – функция последующего поиска файла, удовлетворяющая условиям поиска в функции FindFirst, она возвращает 0, если файл найден;

Procedure FindClose(var F: TSearchRec); – освобождение памяти,

выделенной ранее функцией FindFirst.

Рассмотрим пример применения этих трех функций. На форме должны быть помещены следующие компоненты:

Edit1 – для задания образа искомого файла, например, ’*.pas’ – для поиска всех файлов с расширением pas;

CheckBox1 – для задания атрибутов искомых файлов; StringGrid1 – для вывода имен и длин найденных файлов; Button1 – для запуска процесса поиска файлов.

Тогда обработчик события нажатия кнопки будет выглядеть следующим образом:

Procedure TForm1.Button1Click(Sender: TObject);

Var sr: TSearchRec;// Запись для параметров найденного файла FileAttrs: Integer; // Переменная для задания атрибута искомых файлов begin

StringGrid1.RowCount := 1; // Задаем одну строку для вывода имен файлов

64