Процедуры и функции для работы с файлами
Ниже описываются процедуры и функции, которые можно использовать с файлами любого вида. Специфика работы с типизированными, текстовыми и нетипизированными файлами рассматривается в следующих разделах.
Процедура Close.
Закрывает файл, однако связь файловой переменной с именем файла, установленная ранее процедурой ASSIGN, сохраняется. Формат обращения:
CLOSE (<ф.п.>)
При создании нового или расширении старого файла процедура обеспечивает сохранение в файле всех новых записей и регистрацию файла в каталоге. Функции процедуры CLOSE выполняются автоматически по отношению ко всем открытым файлам при нормальном завершении программы. Поскольку связь файла с файловой переменной сохраняется, файл можно повторно открыть без дополнительного использования процедуры ASSIGN.
Процедура RENAME.
Переименовывает файл. Формат обращения:
RENAME (<ф.п.>, <новое имя>)
Здесь <новое имя> - строковое выражение, содержащее новое имя файла. Перед выполнением процедуры необходимо закрыть файл, если он ранее был открыт процедурами RESET, REWRITE или APPEND.
Процедура ERASE.
Уничтожает-файл. Формат обращения:
ERASE (<ф.п.>)
Перед выполнением процедуры необходимо закрыть файл, если он ранее был открыт процедурами RESET, REWRITE или APPEND.
Следующий фрагмент программы показывает, как можно использовать процедуры RENAME и CLOSE при работе с файлами. Предположим, что требуется отредактировать файл, имя которого содержит переменная NAME. Перед редактированием необходимо убедиться, что нужный файл имеется на диске, и переименовать его - заменить расширение этого файла на ВАК (страховочная копия). Если файл с таким расширением уже существует, его надо стереть.
var
fi : text; {Исходный файл}
fo : text; {Отредактированный файл}
name : String;
name_bak: String;
k, i: Word;
const
bak = '.bak';
begin
.......
{Получаем в name bak имя файла с расширением .ВАК:}
k := pos('.',name);
if k = 0 then
k := length(name) +1;
name_bak := copy(name,1,k-1) + bak;
{Проверяем существование исходного файла:}
assign(fi,name);
{$I-} ' reset(fi);
if lOResult <> 0 then
halt; {Завершаем программу: файла не существует}
close(fi); ,
{Проверяем существование .ВАК-файла:}
assign(fо,name_bak);
reset (fo);
{$I+}
if lOResult = 0 then
begin {Файл .ВАК существует:}
close(fo); {Закрываем его}
erase(fo) {и уничтожаем}
end;
{Проверки закончены, подготовка к работе:}
rename(f i,name_bak);
reset(fi);
assign(fo,name);
rewrite(fo);
.......
end.
Обратите внимание: проверка на существование файла .ВАК в данном примере необходима, так как обращение
rename(fi,name_bak);
вызовет ошибку в случае, если такой файл существует.
Процедура FLUSH.
Очищает внутренний буфер файла и, таким образом, гарантирует сохранность всех последних изменений файла на диске. Формат обращения:
FLUSH (<ф.п.>)
Любое обращение к файлу в Турбо Паскале осуществляется через некоторый буфер, что необходимо для согласования внутреннего представления файлового компонента (записи) с принятым в ДОС форматом хранения данных на диске. В ходе выполнения процедуры FLUSH все новые записи будут действительно записаны на диск. Процедура игнорируется, если файл был инициирован для чтения процедурой RESET.
Функция EOF (<ф. п. >) : BOOLEAN.
Логическая функция, тестирующая конец файла. Возвращает TRUE, если файловый указатель стоит в конце файла. При записи это означает, что очередной компонент будет добавлен в конец файла, при чтении -что файл исчерпан.
Процедура CHDIR.
Изменение текущего каталога. Формат обращения:
CHDIR (<путь>)
Здесь <путь> - строковое выражение, содержащее путь к устанавливаемому по умолчанию каталогу.
Процедура GETDIR.
Позволяет определить имя текущего каталога (каталога по умолчанию). Формат обращения:
GETDIR (<устройство>, <каталог>)
Здесь <устройство> - выражение типа WORD , содержащее номер устройства: 0 - устройство по умолчанию, 1 - диск А, 2 - диск В и т.д.;
<каталог> - переменная типа STRING, в которой возвращается путь к текущему каталогу на указанном диске.
Процедура MKDIR.
Создает новый каталог на указанном диске. Формат обращения:
MKDIR (<каталог>)
Здесь <каталог> - выражение типа STRING, задающее путь к каталогу. Последним именем в пути, т.е. именем вновь создаваемого каталога не может быть имя уже существующего каталога.^
Процедура RMDIR.
Удаляет каталог. Формат обращения:
RMDIR (<каталог>)
Удаляемый каталог должен быть пустым, т.е. не содержать файлов или имен каталогов нижнего уровня.
Функция IORESULT: WORD.
Возвращает условный признак последней операции ввода-вывода.
Если операция завершилась успешно, функция возвращает ноль. Коды ошибочных операций ввода-вывода представлены в прил.З. Следует помнить, что IORESULT становится доступной только при отключенном автоконтроле ошибок ввода-вывода. Директива компилятора {$I-} отключает, а директива {$I+} включает автоконтроль. Если автоконтроль отключен, а операция ввода-вывода привела к возникновению ошибки, устанавливается флаг ошибки и все последующие обращения к вводу-выводу блокируются, пока не будет вызвана функция IORESULT.
Ряд полезных файловых процедур и функций становится доступным при использовании библиотечного модуля DOS.TPU, входящего в стандартную библиотеку TURBO. TPL . Эти процедуры и функции указаны ниже. Доступ к ним возможен только после объявления USES DOS в начале программы (подробнее о работе с модулями см. гл.9).
Функция DISKFREE (<диск>) : LONGINT.
Возвращает объем в байтах свободного пространства на указанном диске. При обращении к функции выражение <диск> типа BYTE определяет номер диска: 0 - устройство по умолчанию, 1 - диск А , 2 - диск В и т.д. Функция возвращает значение -1, если указан номер несуществующего диска.
Функция DISKSIZE (<диск>) : LONGINT.
Возвращает полный объем диска в байтах или -1 , если указан номер несуществующего диска.
Процедура FINDFIRST.
Возвращает атрибуты первого из файлов, зарегистрированных в указанном каталоге. Формат обращения:
FINDFIRST (<маска>, <атрибуты>, <имя>)
Здесь <маска> - строковое выражение, содержащее маску файла;
<атрибуты> - выражение типа BYTE, содержащее уточнение к маске (атрибуты); <имя> - переменная типа SEARCHREC, в которой будет возвращено имя файла.
При формировании маски файла используются следующие символы-заменители ДОС:
* означает, что на месте этого символа может стоять сколько угодно (в том числе ноль) разрешенных символов имени или расширения файла;
? означает, что на месте этого символа может стоять один из разрешенных символов.
Например:
* . * выбирает все файлы из каталога;
с* . * выбирает все файлы с именами, начинающимися на с (cl.pas,сс!2345, c.dat и т.д.);
a?.dat выбирает имена файлов типа a0.dat, az.dat и т.д.
Маске может предшествовать путь'. Например, команда
с:\dir\subdir\*.pas
эзначает выбирать все файлы с расширением .PAS из каталога SUBDIR, находящегося на диске С; каталог SUBDIR зарегистрирован в каталоге верхнего уровня DIR, который, в свою очередь, входит в корневой каталог.
Байт <атрибуты> содержит двоичные разряды (биты), уточняющие, к каким именно файлам разрешен доступ при обращении к процедуре FINDFIRST . Вот как объявляются файловые атрибуты в модуле DOS. TPU:
const
Readonly = $01; {только чтение}
Hidden = $02; {скрытый файл}
SysFile = $04; {системный файл}
VolumeID = $08; {идентификатор тома}
Directory = $10; {имя подкаталога}
Archive =$20; {архивный файл}
AnyFile= $3F; {любой файл}
Комбинацией бит в этом байте можно указывать самые разные варианты, например $ 06 - выбирать все скрытые и/или системные файлы.
Результат работы процедуры FINDFIRST возвращается в переменной типа SEARCHREC. Этот тип в модуле DOS. TPU определяется следующим образом:
type
SearchRec = record
Fill : array [1..21] of Byte;
Attr : Byte;
Time : LongInt;
Size : LongInt;
Name : String.[12]
end;
Здесь Attr - атрибуты файла (см. выше);
Time - время создания или последнего обновления файла; возвращается в упакованном формате; распаковать параметр можно процедурой UNPACKTIME (см.ниже);
Size - длина файла в байтах;
Name - имя и расширение файла. Для распаковки параметра TIME используется процедура
UNPACKTIME(Time: Longlnt; var T:DateTime).
В модуле DOS. TPU объявлен следующий тип DateTime:
type
DateTime = record
year:Word; {год в формате 19ХХ}
month:Word; {месяц I..12}
day:Word; {день 1..31}
hour:Word; {час 0..23}
min:Word; {минуты 0..59}
sec:Word {секунды 0..59}
end;
Результат обращения к процедуре FINDFIRST можно проконтролировать с помощью функции DOSERROR типа WORD, которая возвращает значения:
0 - нет ошибок;
2 - не найден каталог;
18 - каталог пуст (нет указанных файлов).
Процедура FINDNEXT.
Возвращает имя следующего файла в каталоге. Формат обращения:
FINDNEXT (<сл.файл>)
Здесь <сл.фаш> - запись типа SEARCHREC (см. выше), в которой возвращается информация о файле.
Следующая простая программа иллюстрирует способ использования процедур FINDFIRST и FINDNEXT. Программа выводит на экран список всех PAS-файлов текущего каталога:
Uses DOS;
var
S: SearchRec;
begin
FindFirst('*.pas',AnyFile,S);
while DosError = 0 do begin
with S do
WriteLn(Name:12,Size:12);
FindNext(S)
end
end.
Процедура GETFTIME.
Возвращает время создания или последнего обновления файла. Формат обращения:
GETFTIME (<ф.п.>, <время>)
Здесь <время> - переменная типа LONGINT, в которой возвращается время в упакованном формате.
Процедура SETFTIME.
Устанавливает новую дату создания или обновления файла. Формат обращения:
SETFTIME (<ф.п.>, <время>)
Здесь <время> - время и дата в упакованном формате.
Упаковать запись типа DATETIME в переменную типа LONGINT можно процедурой
PACKTIME (var T:DateTime; var Time:LongInt).
(Описание типа DA TETIME см. выше).
Процедура GETFATTR.
Позволяет получить атрибуты файла. Формат обращения:
GETFATTR (<ф.п.>, <атрибуты>)
Здесь <атрибуты> - переменная типа WORD, в младшем байте которой возвращаются устанавливаемые атрибуты файла.
Процедура SETFATTR.
Позволяет установить атрибуты файла. Формат обращения:
SETFATTR (<ф.п.>, <атрибуты>)
Функция FSEARCH: PATHSTR.
Ищет файл в списке каталогов. Формат вызова:
FSEARCH (<имя>, <сп.каталогов>)
Здесь <имя> - имя отыскиваемого файла (строковое выражение или переменная типа PATHSTR; имени может предшествовать путь); <сп.каталогов> - список каталогов, в которых отыскивается файл (строковое выражение или переменная типа STRING); имена каталогов разделяются точкой с запятой.
Результат поиска возвращается функцией FSEARCH в виде строки типа PATHSTR. В строке содержится путь и имя файла, если поиск был успешным, в противном случае возвращается пустая строка.
Тип PATHSTR в модуле DOS.TPU объявлен следующим образом:
type
PathStr = String[79];
Следует учесть, что поиск файла всегда начинается в текущем каталоге и только после этого продолжается в тех, что перечислены в <сп.каталогов>. Если файл обнаружен, дальнейший поиск прекращается, даже если часть каталогов осталась непросмотренной. В частности, если файл зарегистрирован в текущем каталоге, он «заслонит» собой одноименные файлы в других каталогах.
Пусть, например, на диске имеется файл \SUBDIR\MYFILE.PAS. Тогда в случае, если текущий каталог - корневой, обращение
FSEARCH ('MYFILE,PAS','\SUB; \SUBDIR').
вернет строку \SUBDIR\MYFILE.PAS, а обращение
FSEARCH ('MYFILE.PAS1,'\SUB')
вернет пустую строку. Однако, если текущим установлен каталог SUBDIR, то в обоих случаях вернется строка MYFILE.PAS (если файл находится в текущем каталоге,в выходной строке путь к нему не указывается).
Процедура FSPLIT.
«Расщепляет» имя файла, т.е. возвращает в качестве отдельных параметров путь к файлу, его имя и расширение. Формат обращения:
FSPLIT (<файл>, <путь>, <имя>, <расширение>)
Здесь <файл> - строковое выражение, содержащее спецификацию файла (имя с расширением и, возможно, с предшествующим путем);
<путь> - переменная типа DIRSTR=STRING [67], в которой возвращается путь к файлу;
<имя> - переменная типа NAMESTR=STRING [8], в которой возвращается имя файла;
<расширение> - переменная типа EXTSTR=STRING [4], в которой возвращается расширение с предшествующей ему точкой.
Процедура не проверяет наличие на диске указанного файла. В качестве входного параметра может использоваться переменная типа PATHSTR.
Функция FEXPAND: PATHSTR.
Дополняет файловое имя до полной спецификации, т.е. с указанием устройства и пути. Формат вызова:
FEXPAND (<файл>)
Здесь <файл> - строковое выражение или переменная типа PATHSTR.
Функция не проверяет наличие указанного файла на диске, а просто дополняет имя файла недостающими параметрами - текущим устройством и путем к текущему каталогу. Результат возвращается в строке типа PATHSTR.