Процедуры и функции для работы с файлами


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

Процедура 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.