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);
вызовет ошибку в случае, если такой
файл существует.