Ниже описываются процедуры и функции, которые можно использовать с файлами любого вида. Специфика работы с типизированными, текстовыми и нетипизированными файлами рассматривается в следующих разделах.
Таблица 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);
вызовет ошибку в случае, если такой файл существует.