Процедуры и функции для работы с файлами
Ниже описываются процедуры и функции, которые можно использовать с файлами любого вида. Специфика работы с типизированными, текстовыми и нетипизированными файлами рассматривается в следующих разделах. Процедура 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. ТЕКСТОВЫЕ ФАЙЛЫ Текстовые файлы связываются с файловыми переменными, принадлежащими стандартному типу TEXT. Текстовые файлы предназначены для хранения текстовой информации. Именно в такого типа файлах хранятся, например, исходные тексты программ. Компоненты (записи) текстового файла могут иметь переменную длину, что существенно влияет на характер работы с ними. Текстовый файл трактуется в Турбо Паскале как совокупность строк переменной длины. Доступ к каждой строке возможен лишь последовательно, начиная с первой. При создании текстового файла в конце каждой записи (строки) ставится специальный признак EOLN (End OfLiNe - конец строки), а в конце всего файла - признак EOF (End Of File - конец файла). Эти признаки можно протестировать одноименными логическими функциями (см. ниже). При формировании текстовых файлов используются следующие системные соглашения: EOLN- последовательность кодов ASCII #13 (CR) и #10 (LF); EOF - код #26 стандарта ASCII. Для доступа к записям применяются процедуры READ, READLN, WRITE, WRITELN. Они отличаются возможностью обращения к ним с переменным числом фактических параметров, в качестве которых могут использоваться символы, строки и числа. Первым параметром в любой из перечисленных процедур может стоять файловая переменная. В этом случае осуществляется обращение к дисковому файлу или логическому устройству, связанному с переменной процедурой ASSIGN. Если файловая переменная не указана, происходит обращение к стандартным файлам INPUT к OUTPUT. Процедура READ. Обеспечивает ввод символов, строк и чисел. Формат обращения: READ (<ф.п.>,<сп.ввода>) или READ (<сп.ввода>) Здесь <сп.ввода> - список ввода: последовательность из одной или более переменных типа CHAR, STRING, а также любого целого или вещественного типа. При вводе переменных типа CHAR выполняется чтение одного символа из файла и присваивание считанного значения переменной. Если перед выполнением чтения указатель файла достиг конца очередной строки, то результатом чтения будет символ CR (ASCII код #13), а если достигнут конец файла, то - символ EOF (код #26). При вводе с клавиатуры символ CR вводится при нажатии на клавишу Enter, а символ EOF - при одновременном нажатии клавиш CTRL и Z. При вводе переменных типа STRING количество считанных процедурой и помещенных в строку символов равно максимальной длине строки, если только раньше не встретились символы CR или EOF. В этом случае сами символы CR и EOF в строку не помещаются. Если количество символов во входном потоке данных больше максимальной длины строки, «лишние» символы до конца строки отбрасываются,а новое обращение к READ возвращает пустую строку. Таким образом, процедура READ не в состоянии прочесть последовательность строк: первая строка будет прочитана нормально, а все последующие окажутся пустыми. Для ввода последовательности строк нужно использовать процедуру READLN (см. ниже). При вводе числовых переменных процедура READ вначале выделяет подстроку во входном потоке по следующему правилу: все ведущие пробелы, символы табуляции и маркеры конца строк EOLN пропускаются; после выделения первого значащего символа, наоборот, любой из перечисленных символов или символ EOF служат признаком конца подстроки. Выделенная таким образом подстрока затем рассматривается как символьное представление числовой константы соответствующего типа и преобразуется во внутреннее представление, а полученное значение присваивается переменной. Если в подстроке был нарушен требуемый формат представления численной константы, возникает ошибка ввода-вывода. Если при пропуске ведущих пробелов встретился символ EOF, переменная получает значение 0. Отметим, что в Турбо Паскале не предусмотрен ввод шестнадцатеричных констант. При использовании процедуры READ применительно к стандартному файлу INPUT, т.е. при вводе с клавиатуры, символьные строки запоминаются в буфере, который передается процедуре только после нажатия на клавишу Enter. Это позволяет редактировать данные при их вводе. Для редактирования используются следующие клавиши: · Backspace, Ctrl-H, перевод курсора влево - стирают символ слева от курсора; · перевод курсора вправо - восстанавливает символ за символом предыдущую строку ввода; · Ctrl-Z Enter - завершает ввод по процедуре READ; оставшиеся «лишние» символьные параметры принимают значение CHR(26), строки возвращаются пустыми, а численные переменные остаются без изменения. Максимальная длина буфера ввода при работе с клавиатурой составляет 127 символов. Ввод с клавиатуры по процедуре READ сопровождается эхо-повтором вводимых символов на экране ПК. Процедура READ прекрасно приспособлена к вводу чисел. При обращении к ней за вводом очередного целого или вещественного числа процедура «перескакивает» маркеры конца строк, т.е. фактически весь файл рассматривается ею как одна длинная строка, содержащая текстовое представление чисел. В сочетании с проверкой конца файла функцией EOF процедура READ позволяет организовать простой ввбд массивов данных, например, так: const N = 1000; {Максимальная длина ввода} var f: text; m: array [1..N] of real; i: Integer; begin assign(f, 'prog.dat'); reset(£); i:= 1; while not EOF(f) and (i <= N) do begin read(f,m[i]); inc(i) end; close(f); ....... end. Процедура READLN. Обеспечивает ввод символов, строк и чисел. Эта процедура идентична процедуре READ за исключением того, что после считывания последней переменной оставшаяся часть строки до маркера EOLN пропускается, поэтому следующее обращение к READLN или READ начинается с первого символа новой строки. Кроме того, эту процедуру можно вызвать без параметра <cn.вводa> (см. процедуру READ), что приведет к пропуску всех символов текущей строки вплоть до EOLN. Если процедура используется для чтения с клавиатуры, нажатие на клавишу Enter отобразится на экране как последовательность CR + LF и курсор будет помещен в начало следующей строки, в то время как в процедуре READ эхо-повтором клавиши Enter является символ CR и курсор помещается в начало текущей строки. Процедура WRITE. Обеспечивает вывод информации в текстовый файл или передачу ее на логическое устройство. Формат обращения: WRITE (<ф.п.>, <сп.вывода>) или WRITE (<сп.вывода>) Здесь <сп.вывода> - список вывода: последовательность из одного или более выражений типа CHAR, STRING, BOOLEAN, a также любого целого или вещественного типа. Файловая переменная <ф.п.>, если она указана, должна быть предварительно описана как переменная типа TEXT и связана с именем файла или логическим устройством процедурой ASSIGN. Если файловая переменная отсутствует, подразумевается вывод в стандартный файл OUTPUT, который обычно связан с экраном ПК. Любой элемент списка вывода может иметь форму OutExpr [: MinWidth [: DecPlaces ] ] Здесь OUTEXPR - выводимое выражение; MINWIDTH, DECPLACES - выражения типа WORD (квадратные скобки означают возможность отсутствия заключенных в них параметров). Подпараметр MINWIDTH, если он присутствует, указывает минимальную ширину поля, в которое будет записываться символьное представление значения OUTEXPR. Если символьное представление имеет меньшую длину, чем MINWIDTH, оно будет дополнено слева пробелами, если - большую длину, то подпараметр MINWIDTH игнорируется и выводится необходимое число символов. Подпараметр DECPLACES задает количество десятичных знаков в дробной части вещественного числа. Он может использоваться только совместно с MINWIDTH и только по отношению к выводимому выражению одного из вещественных типов. Если ширина поля вывода не указана, соответствующий параметр выводится вслед за предыдущим без какого-либо их разделения. Символы и строки передаются выводному файлу без изменений, но снабжаются ведущими пробелами, если задана ширина поля вывода и эта ширина больше требуемой для вывода. При выводе логических выражений в зависимости от их значения выводятся строки TRUE или FALSE. (Ввод логических констант процедурами READ или READLN не предусмотрен). Вещественные числа выводятся в экспоненциальном формате, если не указан подпараметр DECPLACES, в противном случае выбирается формат представления числа с фиксированной точкой. Экспоненциальный формат представляет вещественное число в виде _s#.##############E*####, где: _ пробел; s пробел для положительного и знак «-» для отрицательного чисел; # десятичная цифра; Е символ десятичного основания; * знак «+» или «-» в зависимости от знака десятичного порядка числа. Если подпараметр MINWIDTH опущен, принимается его значение по умолчанию (23). Если MINWIDTH меньше 10, считается, что он равен 10. Если подпараметр DECPLACES равен нулю, ни дробная часть числа, ни десятичная точка не выводятся. При отрицательном значении DECPLACES этот параметр игнорируется и число выводится в экспоненциальном формате с учетом MINWIDTH. Если значение DECPLACES больше 18, принимается значение 18. Следует учесть, что при указании подпараметра DECPLACES вещественное число всегда будет выводиться в формате с фиксированной точкой и требуемым количеством знаков в дробной части, даже если значение подпараметра MINWIDTH окажется недостаточным для размещения целой части: в этом случае значение MINWIDTH автоматически увеличивается. При выводе на экран в случае, когда длина выводимой последовательности символов превышает ширину экрана или созданного на нем окна, «лишние» символы переносятся на следующую экранную строку. При заполнении экрана или окна его содержимое сдвигается вверх на одну строку. Процедура WRITELN. Эта процедура полностью идентична процедуре WRITE за исключением того, что выводимая строка символов завершается кодами CR и LF. При вызове WRITELN можно опускать параметр <сп.вывода>: в этом случае в файл передается маркер EOLN, что при выводе на экран приведет к переводу курсор» в начало следующей строки. Логическая функция EOLN. Возвращает TRUE, если во входном текстовом файле достигнут маркер конца строки. Формат обращения: EOLN<ф.п.> Если параметр <ф.п.> опущен, функция проверяет стандартный файл INPUT. Существует некоторое отличие в работе функций EOLN и EOF с дисковыми файлами и логическими устройствами. Дело в том, что для логического устройства невозможно предвидеть, каким будет результат чтения очередного символа. Поэтому при работе с логическим устройством функция EOLN возвращает TRUE, если последним считанным с устройства символом был EOLN или EOF, в то время как при чтении с диска TRUE возвращается в случае, если следующим считываемым символом будет EOLN или EOF. Аналогичное различие наблюдается и в функции EOF: для логического устройства TRUE возвращается в случае, если последним символом был EOF, а при чтении с диска - если следующим считываемым символом будет EOF. Иными словами, функции тестируют соответствующие признаки для логического устройства после очередного чтения, а для файла - перед чтением. Логическая функция SEEKEOLN. Пропускает все пробелы и знаки табуляции до маркера конца строки EOLN или до первого значащего символа и возвращает TRUE, если маркер обнаружен. Формат обращения: SEEKEOLN (<ф.п.>) Если параметр <ф.п.> опущен, функция проверяет стандартный файл INPUT. Логическая функция SEEKEOF. Пропускает все пробелы, знаки табуляции и маркеры конца строки EOLN до маркера конца файла или до первого значащего символа и возвращает TRUE, если маркер обнаружен. Формат обращения: SEEKEOF (<ф.п.>) Если параметр <ф.п.> опущен, функция проверяет стандартный файл INPUT. В следующем примере, иллюстрирующем работу с текстовым файлом, подсчитывается общее количество символов в файле и результат делится на 40000 - таким способом можно оценить объем рукописи в так называемых учетно-издательских листах: var f: text; s: String; const Sum: LongInt = 0; {Здесь будет количество символов} begin Write('Имя файла: '); {Запрашиваем...} Readln(s); {и вводим имя файла.} assign(f,s); Reset (f); {Открываем файл} while not EOF(f) do {Подсчитываем...} begin {количество...} ReadLn(f,s); {символов...} inc(Sum, Length(s)) {в файле} end; Close(f); {Закрываем файл} WriteLn('Объем = ', Sum/40000: 6:2,' уч.изд.л.') end.
Читайте также: A) функции государства Воспользуйтесь поиском по сайту: ©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|