11.2. ПРОЦЕДУРЫ И ФУНКЦИИ ДЛЯ РАБОТЫ С ФАЙЛАМИ

Ниже описываются процедуры и функции, которые можно использовать с файлами любого вида. Специфика работы с типизированными, текстовыми и нетипизированными файлами рассматривается в следующих разделах.

Таблица 11.1. Подпрограммы для работы с файлами

Procedure AssignFile(var F; FileName:

String) ;

Связывает файловую переменную f с именем файла FileName

function ChangeFileExt

(const FileName, Ex

tension: String):

Strings;

Изменяет существующее расширение файла на расширение, заданное параметром Extension

 

 

 

Procedure ChDir(Path:

String);

Изменяет текущий каталог: path - строковое выражение, содержащее путь к устанавливаемому по умолчаниюкаталогу

Procedure CloseFile

(var F) ;

 

 

Закрывает файл, однако связь файловой переменной F с именем файла, установленная ранее процедурой Assign-File, сохраняется. При создании нового или расширении старого файла процедура обеспечивает сохранение в файле всех новых записей и регистрацию файла в каталоге. Функции процедуры CloseFile выполняются автоматически по отношению ко всем открытым файлам при нормальном завершении программы. Поскольку связь файла с файловой переменной сохраняется, файл можно повторно открыть без дополнительного использования Процедуры AssignFile

function DateTime-ToFileDate(DateTime: TDateTime): Integer;

Преобразует значение DateTime в системный формат времени создания (обновления) файла

Function DiskFree(D:

Byte): Longint;

 

Возвращает объем в байтах свободного пространства на указанном диске: D - номер диска (0 - устройство по умолчанию, 1 - диск А ,2- диск В и т, д.). Функция возвращает значение -1, если указан номер несуществующего диска

function Delete-

File(const FileName:

String): Boolean;

Уничтожает файл с именем (и, возможно, маршрутом доступа) FileName. Возвращает True, если операция прошла успешно

Function DiskSize(D:

Byte) : Longing;

 

Возвращает объем в байтах полного пространства на указанном диске: d - номер диска (0 - устройство по умолчанию, 1 - диск А ,2- диск Д и т. д.). Функция возвращает значение -1, если указан номер несуществующего диска

Function EOF (var F) :

Boolean;

Тестирует конец файла и возвращает True, если файловый указатель стоит в конце файла. При записи это означает, что очередной компонент будет добавлен в конец файла, при чтении - что файл исчерпан

Procedure Erase(var

F);

Уничтожает файл f. Перед выполнением процедуры не

обходимо закрыть файл (см. замечание ниже)

function FileAge(const

FileName: String): In

teger;

Для файла FileName возвращает время его последнего обновления (в системном формате) или -1, если такого файла не существует

function ExcludeTrai-

lingBackslash(const S: String): Strings;

Исключает из строки s замыкающий символ “\” (если этот символ не замыкает строку, возвращает S без изменения)

function ExpandUNC-

FileName(const File

Name: String): String;

Дополняет имя файла текущим сетевым каталогом (и

диском)

function ExtractFile-

Dir(const FileName:

String): Strings;

Извлекает из полного имени файла маршрут доступа к нему (без последнего символа “\”)

function ExtractFileExt(const FileName:

String): Strings;

Извлекает из полного имени файла его расширение (с ведущей точкой)

function ExtractFileName(cons t Fi1eName:

String): Strings;

Извлекает из полного имени файла его имя (с расширением)

function ExtractFilePath(const File

Name: String): Strings;

Извлекает из полного имени файла маршрут доступа к нему (с последним символом “\”)

function ExtractRela-

tivePath(const Bas eName, De s tName:

String): Strings;

Извлекает из полного имени файла имя маршрута относительно DestName (промежуточные каталоги заменяются символами “..\”)

function ExtractShort-

PathName(const File

Name : String): Strings;

Преобразует имя файла к короткому формату 8.3 для MSDOS и Windows 3-х

function FileDateTo-

DateTime(FileDate: Integer) : TDateTime;

Преобразует системный формат FileDate времени создания файла в формат дата-время

Function FileEx-

ists(const FileName: String): Boolean;

Возвращает True, если файл с именем (и, возможно, маршрутом доступа) FileName существует

function File Get Date

(Handle: Integer): Integers;

По заданному дескриптору файла Handle возвращает время и дату его создания в системном формате. Возвращает 0 в случае успеха или код ошибки

function FileSetDate

(Handle: Integer; Age:

Integer): Integers;

Для файла с дескриптором Handle устанавливает новое время и дату его создания Age в системном формате.

Возвращает 0 в случае успеха или код ошибки

Function FindFirst

(const Path: String;

Attr: Integer; var F:

TSearchRec): Integer;

 

Возвращает атрибуты первого из файлов, зарегистрированных в указанном каталоге: Path - маршрут поиска и маска выбора файлов; Attr - атрибуты выбираемых файлов; f - переменная типа TSesrchRec, в которой будет возвращено имя первого выбранного файла. При успешном поиске возвращает значение 0

Procedure Find- Close(var F: TSear-

chRec);

Освобождает память, выделенную для поиска файлов функциями FindFirst/FindNext

Function FindNext(var

F: TSearchRec): Integer;

Возвращает в переменой f имя следующего файла в каталоге. Переменная f должна предварительно инициироваться обращением к функции FindFirst. При успешном поиске возвращает значение 0

Procedure Flush(varF);

Очищает внутренний буфер файла и, таким образом, гарантирует сохранность всех последних изменений файла на диске

Procedure GetDir(D:

Byte; var S: Strings-

 

 

Возвращает имя текущего каталога (каталога по умолчанию): d - номер устройства (0 - устройство по умолчанию, 1 - диск А, 2- диск В и т. д.); s - переменная типа String, в которой возвращается путь к текущему каталогу на указанном диске

function IncludeTrailingBackslash(const S:String): String;

Возвращает полный маршрут доступа к файлу с ведомым символом “\”

Function lOResult: In

teger;

Возвращает условный признак последней операции ввода-вывода

function IsPathDelimiter(const S: String;

Index: Integer): Boo

lean;

Возвращает True, если в строке S символ index есть “\”.

 

function MatchesMask

(const Filename, Mask:

String): Boolean;

Возвращает True, если имя FileName соответствует групповому имени Mask

Procedure MkDir(Dir:

String) ;

 

 

Создает новый каталог на указанном диске: Dir маршрут поиска каталога. Последним именем в маршруте, т.е. именем вновь создаваемого каталога, не может быть имя уже существующего каталога

procedure ProcessPath

(const EditText:

String; var Drive:

Char; var DirPart:

String; var FilePart:

String) ;

Возвращает имя диска, маршрут поиска и имя файла в переменных Drive, DirPart и FilePart соответственно. EditText - полное имя файла

 

 

 

Procedure Rename(var

F; NewName: String);

Переименовывает файл F; NewName -' строковое выражение, содержащее новое имя файла. Перед выполнением процедуры необходимо закрыть файл только для не типизированных файлов и указывает раз мер блока данных

Procedure Resetfvar F: File; RecSize: Word]);

Открывает существующий файл. RecSize имеет смысл

Procedure Rewrite(varFile [; Recsize: ,Word]) ;

Создает новый файл. Recsize имеет смысл только для не типизированных файлов и указывает размер блока данных

Procedure RmDir(Dir:String);

 

 

Удаляет каталог Dir. Удаляемый каталог должен быть пустым, т. е. не содержать файлов или имен каталогов нижнего уровня

С каждой файловой переменой в момент открытия файла связывается структура данных, которая в числе прочих содержит поле Handle - системный дескриптор файла. Это поле следует использовать При обращении К функциям FileGetTime и FileSetTime. Эти функции, а также функция FileAge и поле Time записи TsearchRec (см. ниже) оперируют системным форматом времени-даты, который можно перевести в стандартный тип дата-время с помощью функции FileDateToDateTime (функция DateTimeToFileDate Осуществляет обратное преобразование).

Подпрограммы FindFirst, FindNext И FindClose позволяют получить

доступ к группе файлов, объединенных общими признаками. Эти признаки при обращении к функции FindFirst указываются маской выбора файлов и их атрибутами.

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

* означает, что на месте этого символа может стоять сколько угодно (в том числе ноль) разрешенных символов имени или расширения файла;

? означает, что на месте этого символа может стоять один из разрешенных символов.

Например:

* . * выбирает все файлы из каталога;

с* . * выбирает все файлы с именами, начинающимися на с

fcl.pas, ccl2345, с.dat И Т.Д.);

а? . dat выбирает имена файлов типа ао. dat, az. dat и т. д.

Маске выбора может предшествовать маршрут поиска файлов. Например, команда

C:\Dir\SubDir\*.pas

означает выбирать все файлы с расширением .раз из каталога Sub-Dir, находящегося на диске с; каталог subDir зарегистрирован в каталоге верхнего уровня Dir, который, в свою очередь, входит в корневой каталог. Если маршрут не указан, файлы ищутся в текущем каталоге.

Параметр Attr при обращении к FindFirst содержит двоичные разряды (биты), уточняющие, к каким именно файлам разрешен доступ. Вот как объявляются файловые атрибуты в модуле SysUtils:

const

faReadOnly = $01; // Только чтение

faHidden = $02; // Скрытый файл

faSysFile = $04; // Системный файл

faVolumeID = $08; // Идентификатор тома

faDirectory = $10; // Имя подкаталога

faArchive = $20; // Архивный файл

faAnyFile = $3F; // Любой файл

Комбинацией бит в этом байте можно указывать самые разные варианты, например $06 - выбирать все скрытые и/или системные файлы.

Результат работы процедуры FindFirst возвращается в переменной типа TSearchRec. Этот тип определяется следующим образом:

type

TSearchRec = record

Time : Integer;

Size : Integer;

Attr : Integer;

Name : TFileName;

ExcludeAttr: Integer;

FindHandle : THandle;

FindDate : Twin32FindDate;

end;

Здесь Attr - атрибуты файла (см. выше); Time - время и дата создания или последнего обновления файла в системном формате; size - длина файла в байтах; Name - имя и расширение файла; FindDate -содержит дополнительную информацию о файле (время создания, время последнего доступа).

Результат обращения к процедуре FindFist возвращается в значении типа integer, которое равно 0, если нет ошибок.

Следующая простая программа иллюстрирует способ использования функций PindFirst И FindNext. Программа выводит в окно многострочного редактора mmoutput список всех файлов, маска выбора которых (и, возможно, маршрут поиска) указана в окне edInput:

procedure TfmExample.bbRunClick(Sender: TObject);

var

Mask: String;

SR: TSearchRec;

begin

Mask := edInput.Text;

if Mask = '' then Mask := '*.*';

mmOutput.Lines.Clear;

if FindFirst(Mask,faAnyFile,SR)=0 then

repeat

mmOutput.Lines.Add(SR.Name);

until FindNext(SR)<>0

FindClose(SR);

end;

Любое обращение к файлу в Object Pascal осуществляется через некоторый буфер, что необходимо для согласования внутреннего представления файлового компонента (записи) с принятым в ОС форматом хранения данных на диске. В ходе выполнения процедуры Flush все новые записи будут действительно записаны на диск. Процедура игнорируется, если файл был инициирован для чтения процедурой Reset.

Функция IOResuit досталась Object Pascal в наследство от Турбо Паскаля. Она используется следующим образом: перед фрагментом программы, в котором может возникнуть ошибка ввода/вывода, ставится директива {$!-}, отключающая автоконтроль операций ввода/вывода. После выполнения опасного участка автоконтроль включается вновь директивой {$!+} и вызывается функция IOResuit. Если операция завершилась успешно, функция возвращает ноль. Следует помнить, что IOResuit становится доступной только при отключенном автоконтроле ошибок ввода/вывода. Если автоконтроль отключен, а операция ввода-вывода привела к возникновению ошибки, устанавливается флаг ошибки и все последующие обращения к вводу/выводу блокируются, пока не будет вызвана функция IOResuit. Вот как можно проверить существование файла с использованием функции IOResuit:

var

F: File;

begin

AssignFile(F,'MyFile') ;

{$!-} // Отключаем автоконтроль Reset(F);

// Пытаемся открыть файл

{$!+} // Включаем автоконтроль

if IOResult=0 then

// Файл существует

else

// Файл не существует

end;

В Object Pascal для защиты программы от краха при выполнении потенциально опасных фрагментов широко используется механизм обработки исключительных ситуаций. Следующий фрагмент показывает, как можно использовать этот механизм при работе с файлами. Предположим, что требуется отредактировать файл, имя которого содержит переменную Name. Перед редактированием необходимо убедиться, что нужный файл имеется на диске, и создать его страховочную копию с расширением вак. Если одноименный файл (т. е. с таким же именем и расширением вак) уже существует, его надо стереть.

var

Fi : TextFile; // Исходный файл

Fo : TextFile; // Отредактированный файл

Name : String;

Name_bak : String;

const

ВАК = '.bak';

begin

// Получаем в name_bak имя файла с расширением .ВАК:

Name_bak := Name - ExtractFileExt(Name) + ВАК;

// Проверяем существование исходного файла:

AssignFile(Fi,Name) ;

try

Reset(Fi) ;

except

Halt; // Завершаем программу: файла не существует

end;

CloseFile(Fi) ;

// Проверяем существование .ВАК-файла:

AssignFile(Fo,Name_bak) ;

try

Reset(Fo) ;

// Файл .ВАК существует:

CloseFile(Fo); // Закрываем его Erase(Fo)

// и уничтожаем

except

end;

// Проверки закончены, подготовка к работе:

Rename(Fi,Name__bak) ;

Reset-(Fi) ;

AssignFile(Fo,Name);

Rewrite(Fo);

end.

Обратите внимание: проверка на существование файла вак в данном примере необходима, так как обращение

Rename(Fi,Name_bak);

вызовет ошибку в случае, если такой файл существует.