Учебное пособие по курсу Программирование на языке высокого уровня для вузов по специальности 230105 Программное обеспечение вычислительной техники и автоматизированных систем
Скачать 0.64 Mb.
|
ЛЕКЦИЯ 17. Процедуры и функции для работы с файлами . Ниже описываются процедуры и функции, которые можно использовать с файлами любого вида. Специфика работы с типизированными, текстовыми и нетипизированными файлами рассматривается в следующих разделах. Процедура CLOSE. Закрывает файл,однако связь файловой переменной с именем файла, устанавливается ранее процедурой ASSIGN, сохраняется. Формат сообщения: CLOSE(<ф.п.>) При создании нового или расширении старого файла процедура обеспечивает сохранение в файле всех новых записей и регистрацию файла в каталоге. Функции процедуры CLOSE выполняется автоматически по отношению ко всем открытым файлам при нормальном завершении программы. Поскольку связь файла с файловой переменной сохраняется, файл можно повторно открыть без дополнительного использования процедуры ASSIGN. Процедура RENAME. Переименовывает файл. Формат сообщения: RENAME(<ф.п.>,<новое имя>); Здесь <новое имя>-строковое выражение, содержащее новое имя файла. Перед выполнением процедуры необходимо закрыть файл, если он ранее был открыт процедурами RESET, REWRITE или APPEND. Процедура ERASE. Уничтожает файл. Формат обращения: ERASE (<ф.п.>) PDF created with pdfFactory Pro trial version www.pdffactory.com 30 Перед выполнением процедуры необходимо закрыть файл, если он ранее был открыт процедурами RESET, PEWRITE или APPEND. Следующий фрагмент программы показывает, как можно использовать процедуры RENAME и CLOSE при работе с файлами. Предположим, что требуется отредактировать файл, имя которого содержит переменная NAME. Перед редактированием необходимо убедится, что нужный файл имеется на диске, и переименовать егозаменить расширение этого файла на .BAK (страховочная копия). Если файл с таким расширением уже существует, его надо стереть. var fi:text; fo:text; name : string; { Исходный файл } name_bak : string; { Отредактированный файл } k,i :word; const bak ='.bak'; { Получить в name_bak имя файла с расширением .BAK: } k:=pos('.',name); if k=0 then k:=lengt(name)+1; name_bak:=copy(name,1,k-1)+bak; { Проверить существование исходного файла: } assign (fi,name); {$I-} reset(fi); if IoResult <> 0 then halt; { Файл не существует } сlose (fi); { Проверить существование BAK-файла } assign(fo,name_bak); {$I+} if IoResuit = 0 then begin { Файл .BAK существует: } close(fo); erase (fo); end; { Проверки закончены, подготовка к работе : } rename (fi,name_bak); reset (fi); assign (fo,name); rewrite(fo); PDF created with pdfFactory Pro trial version www.pdffactory.com 31 Процедура FLUSH. Очищает внутренний буфер файла и, таким образом, гарантирует сохранность всех последних изменений файла на диске. Формат обращения : FLUSH(<ф.п.>) Любое обращение к файлу в Турбо Паскале осуществляется через некоторый буфер, что необходимо для согласования внутреннего представления файлового компонента (записи) с принятым в ДОС форматом хранения данных на диске. В ходе выполнения процедуры FLUSH все новые записи будут действительно записаны на диск. Процедура игнорируется, если файл был инициирован для для чтения процедурой RESET. Функция EOF (< ф . п .>):Boolean. Логическая функция, тестирующая конец файла. Возвращает TRUE, если файловый указатель стоит в конце файла. При записи это означает, что очередной компонент будет добавлен в конец файла, при чтении- что файл исчерпан. Процедура CHDIR. Изменение текущего каталога.Формат обращения: CHDIR(<путь>) Здесь <путь>-строковое выражение, содержащее путь к устанавливаему по умолчанию каталогу. Процедура GETDIR. Позволяет определить имя текущего каталога (каталога по умолчанию). Формат обращения: GETDIR(<устройство>,<каталог>) Здесь <устройство>- выражение типа WORD, содержащее номер устройства: 0- устройство по умолчанию,1- диск A, 2- Диск B и т.д.; PDF created with pdfFactory Pro trial version www.pdffactory.com 32 <каталог>- переменная типа STRING, в которой возвращается путь к текущему каталогу не указанном диске. Процедура MKDIR. Создает новый каталог на указанном диске. Формат обращения: MKDIR(<каталог>) Здесь <каталог>- Выражение типа STRING, задающее путь к каталогу. Последним именем в пути, т.е. именем вновь создоваемого каталога не может быть имя уже существующего каталога. Процедура RMDIR. Удаляет каталог. Формат обращения: RMDIR (<каталог>) Удаляемый каталог должен быть пустым, т.е. не содержать файлов или имен каталогов нижнего уровня. Функция IORESULT:WORD. Возвращает условный признак последней операции ввода-вывода. Если операция завершилась успешно, функция возвращает ноль. Следует помнить, что IORESULT становится доступной только при отключенном автоконтроле ошибок ввода-вывода. Директива компилятора{I-} отключает, а дирректива{I+} включает автоконтроль. Если автоконтроль устанавливает флаг ошибки и все последующие обращения к вводу-выводу блокируется, пока не будет вызвана функция IORESULT. Ряд полезных файловых процедур и функций становится доступным при использовании библиотечного модуля DOS.TRU, входящего в стандартную библиотеку TURBO.TRL.Эти процедуры и функции указаны ниже. Доступ к ним возможен только после объявления USES DOS в начале программы. Функция DISKFREE(< диск >):LONGINT. Возвращает объем в байтах свободного пространства на указанном диске. При обращении к функции выражение <диск> типа BYTE PDF created with pdfFactory Pro trial version www.pdffactory.com 33 определяет номер диска:0- устройство по умолчанию,1- диск A, 2- диск B и т.д. Функция возвращает значение-1, если указан номер несуществующего диска. Функция DISKSIZE(< диск >):LONGINT. Возвращает полный обьем диска в байтах или-1, если указан номер несуществующего диска. Процедура FINDFIRST. Возвращает атрибуты первого из файлов, зарегистрированных в указанном каталоге. Формат обращения: FINDFIRST (<маска>,<атрибуты>,<имя>) Здесь <маска>- строковое выражение, содержащее маску файла; <атрибуты>-выражение типа BYTE, содержащее уточнение к маске (атрибуты); <имя>- переменная типа SEARCHREC, в которой вудет возвращено имя файла. При формировании маски файла используются следующие символы-заменители ДОС. * означает, что на месте этого символа может стоять сколько угодно (в том числе и ноль ) разрешенных символов имени или расширения файла; ? означает на месте этого символа может стоять один из разрешенных символов. Например: *.* -выбирает все файлы из каталога; c*.* -выбирает все файлы с именами, начинающимися на c(c1.pas,cc12345, c.dat и т.д.); a?.dat -выбирает имена файлов типа a0.dat,az.dat и т.д. Маске может предшевствовать путь. Например,команда c:\dir\subdir\*.pas означает выбирать все файлы с расширением .PAS из каталога SUBDIR, находящегося на диске C; который, в свою очередь, входит в корневой каталог. Байт<атрибуты> содержит двоичные разряды (биты), уточняющие, к каким именно файлам разрешен доступ при общении к процедуре FINDFIRST. Вот так обьявляются файловые атрибуты в модуле DOC.TRU: const ReadOnly =&01; { только чтение } Hidden =&02; { скрытый файл } PDF created with pdfFactory Pro trial version www.pdffactory.com 34 SysFile =&04; { системный файл } VolumelF =&08; { идентификатор тома } Directory =&10; { имя подкаталога } Archive =&20; { архивный файл } AnyFile =&3F; { любой файл } Комбинацией бит в этом байте можно указывать самые разные варианты, например &06- выбирать все открытые и/или системные файлы. Результат работы процедуры FINDFIRST возвращается в переменной типа SEARCHREC. Этот тип в модуле DOS.TRU определяется следующим образом: 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 исрользуется процедура UNPACTIME (Time:longint; var T:DateTime). В модуле DOS.TRU объявлен следующий тип: type DateTime = record year : word; { год в формате 19хх } month : word; { месяц 1..12 } day : word; { день 1..31 } hour : word; { час 0..23 } mit : word; { минуты 0..59 } sec : word; { секунды 0..59 } Результат обращения к процедуре FINDFIRST можно проконролировать с помощью функции DOSERROR типа WORD, которая возвращает значения: 0 - нет ошибок; 2 - не неайден каталог; 18 - каталог пуст (нет указанных файлов). PDF created with pdfFactory Pro trial version www.pdffactory.com 35 Процедура FINDNEXT. Возвращает имя следующего файла в каталоге.Формат обращения: FINDNEXT(<сл.файл>) Здесь <сл.файл> - запись типа SEARCHREC (см.выше), в которой возвращается информация о файле. Следующая простая программа иллюстрирует способ использования процедур FINDFIRST и FINDNEXT. Программа выводит на экран список всех PAS-файлов текущего каталога: Uses DOS; var S:SearchRec; begin FindFirst('*.pas',AniFile,S); while DosError = 0 do begin with S do Writeln(Name:12,Size:12); end end. Процедура GETFTIME. Возвращает время создания или последнего обновления файла. Формат обращения: GETFTIME(<ф.п.>,<время>) Здесь <время> - переменная типа LONGINT, в которой возвращается время в упакованном формате. Процедура SETFTIME. Устанавливает новую дату создания или обновления файла. Формат обращения: SETFTIME(<ф.п.>,<время>) Здесь <время> - время и дата в упакованном формате. Упаковать запись типа DATETIME в переменную типа LONGINT можно процедурой PACKTIME(var T:DateTime; var Time:longint).(Описание типа DATETIME см.выше). Процедура GETFATTR. Позволяет получить атрибуты файла. Формат обращения: GETFATTR(<ф.п.>,<атрибуты>) PDF created with pdfFactory Pro trial version www.pdffactory.com 36 Здесь <атрибуты> - переменная типа WORD, в младшем байте которой возвращаются устанавливаемые атрибуты файла. Процедура SETFATTR. Позволяет установить атрибуты файла. Формат обращения: SETFATTR(<ф.п.>,<атрибуты>) Функция FSEARCH типа PATHSTR. Ищет файл в списке каталогов. Формат обращения: FSEARCH(<имя>,<сп.каталогов>) Здесь <имя> - имя отыскиваемого файла (строковое выражение или переменная типа PATHSTR=STRING[79]; имени может предшествовать путь); <сп.каталогов> - список каталогов, в которых отыскивается файл (строковое выражение или переменная типа STRING); имена каталогов разделяются точкой с запятой. Результат поиска возвращается функцией FSEARCH в виде строки типа PATHSTR=STRING[79]. В строке содержится путь и имя файла, если поиск был успешным, в противном случае возвращается пустая строка. Следует учесть, что поиск файла всегда начинается в текущем каталоге и только после этого продолжается в тех, что перечислены в <сп.каталогов>. Если файл обнаружен, дальнейший поиск прекращается, даже если часть каталогов осталась непросмотренной. В частности, если файл зарегестрирован в текущем каталоге, он "заслонит" собой одноименные файлы в других каталогах. Пусть, например, имеется файл \SUBDIR\MYFILE.PAS. Тогда в случае, если текущий каталог - корневой, обращение FSEARCH ('MYFILE,PAS','\SUB; \SUBDIR') вернет строку \SUBDIR\MYFILE.PAS, а обращение FSEARCH ('MYFILE.PAS','\SUB') вернет пустую строку. Однако, если текущим установлен каталог SUBDIR, то в обоих случаях вернется строка MYFILE.PAS (если файл находится в текущем каталоге, в выходной строке путь к нему не указывается). Процедура FSPLIT. "Расщепляет" имя файла, т.е. возвращает в качестве отдельных параметров путь к файлу, его имя и расширение. Формат обращения: FSPLIT (<файл>,<путь>,<имя>,<расширение>) Здесь <файл> - строковое выражение, содержащее спецификацию файла (имя с расширением и, возможно, с предшествующим путем); PDF created with pdfFactory Pro trial version www.pdffactory.com 37 <путь> - переменная типа DIRSTR=STRING[67], в которой возвращается путь к файлу; <имя> - переменная типа NAMESTR=STRING[8], в которой возвра- щается имя файла; <расширение> - переменная типа EXTSTR=STRING[4], в котором возвращается расширение с предшествующей ему точкой. Процедура не проверяет наличие на диске указанного файла.В качестве входного параметра может использоваться переменная типа PATHSTR=STRING[79]. Функция FEXPAND типа PATHSTR. Дополняет файловое имя до полной спецификации, т.е. с указанием устройства и пути. Формат вызова: FEXPAND (<файл>) Здесь <файл> - строковое выражение или переменная типа PATHSTR. Функция не проверяет наличие указанного файла на диске, а просто дополняет имя файла недостающими параметрами - текущим устройством и путем к текущему каталогу. Результат возвращается в строке типа PATHSTR=STRING[79]. PDF created with pdfFactory Pro trial version www.pdffactory.com 38 ЛЕКЦИЯ 18. ТЕКСТОВЫЕ ФАЙЛЫ . Текстовые файлы связываются с файловыми переменными, принадлежащими стандартному типу TEXT. Текстовые файлы предназначены для хранения текстовой информации. Именно в такого типа файлах хранятся, например,исходные тексты программ. Компоненты (записи) текстового файла могут иметь переменную длину, что существенно влияет на характер работы с ними. Текстовый файл трактуется в Турбо-Паскале как совокупность строк переменной длины. Доступ к каждой строке возможен лишь последовательно, начиная с первой. При создании текстового файла в конце каждой записи (строки) ставится признак EOLN (End of line - конец строки), а в конце всего файла признак 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). При вводе с клавиатуры PDF created with pdfFactory Pro trial version www.pdffactory.com 39 символ CR вводится при нажатии на клавишу "Ввод", а символ EOF - при одновременном нажатии на клавиши CTRL и Z. При вводе переменных типа STRING количество считанных процедурой и помещенных в строку символов равно максимальной длине строки, если только раньше не встретились символы CR и EOF. В этом случае сами символы CR и EOF в строку не помещаются. Если количество символов во входном потоке данных больше максимальной длины строки, "лишние" символы до конца строки отбрасываются, а новое обращение к READ возвращает пустую строку. Таким образом, процедура READ не в состоянии прочесть последовательность строк: первая строка будет прочитана нормально, а все последующие окажутся пустыми. Для ввода последовательности строк нужно использовать процедуру READLN (см.ниже). При вводе числовых переменных процедура READ вначале выделяет подстроку во входном потоке по следующему правилу: все ведущие пробелы, символы табуляции и маркеры конца строк EOLN пропускаются; после выделения первого значащего символа, наоборот, любой из перечисленных символов или символ EOF служат признаком конца подстроки. Выделенная таким образом подстрока потом рассматривается как символьное представление числовой константы соответствующего типа и преобразуется во внутреннее представление, а полученное значение присваивается переменной. Если в подстроке был нарушен требуемый формат представления численной константы, возникает ошибка ввода вывода. Если при пропуске ведущих пробелов встретился символ EOF, переменная получит значение 0. Отметим, что в Турбо-Паскале не предусмотрен ввод шестнадцатиричных констант. При использовании прцедуры READ применительно к стандартному файлу INPUT, т.е. при вводе с клавиатуры, символьные строки запоминаются в буфере, который передается процедуре только после нажатия на клавишу "Ввод". Это позволяет редактировать данные при их вводе. Для редактирования используются следующие клавиши: "Забой", Ctrl-H, перевод курсора влево - стирают символ слева от курсора; перевод курсора вправо - восстанавливает символ за символом предыдущую строку ввода; Ctrl-Z "Ввод" - завершает по процедуре READ; оставшиеся "лишние" символьные параметры принимают значение CHR(26), строки возвращаются пустыми, а численные переменные остаются без изменения. Максимальная длина буфера ввода при работе с клавиатурой составляет 127 символов. Ввод с клавиатуры по процедуре READ сопровождается эхо-повтором вводимых символов на экране ПК. PDF created with pdfFactory Pro trial version www.pdffactory.com 40 Процедура READ прекрасно приспособлена к вводу чисел. При обращении к ней за вводом очередного целого или вещественного числа процедура "перескакивает" маркеры конца строк, т.е. фактически весь файл рассматривается ею как одна длинная строка, содержащая текстовое представление чисел. В сочетании с проверкой конца файла функцией EOF процедура READ позволяет организовать простой ввод массивов данных, например, так: const N = 1000; { максимальная длина ввода } var f : text; m : array [1..N] of real; i : integer; BEGIN assign(f, 'prog.dat'); reset(f); i := 1; while not EOF(f) and (i <= N) do begin read(f,m[i]); inc(i); end; close(f); ПРОЦЕДУРА READLN. Обеспечивает ввод символов, строк и чисел. Эта процедура идентична процедуре READ за исключением того, что после считывания последней переменной оставшаяся часть строки до маркера EOLN пропускается, поэтому следующее обращение к READLN или READ начинается с первого символа новой строки. Кроме того эту процедуру можно вызвать без параметра <сп.ввода> (см.процедуру READ), что приведет к пропуску всех символов текущей строки вплоть до EOLN. Если процедура используется для чтения с клавиатуры, нажатие на клавишу "Ввод" отобразится на экране как последовательность CR+LF и курсор будет помещен в начало следующей строки, в то время как в процедуре READ эхо-повтором клавиши "Ввод" является символ CR и курсор перемещается в начало текущей строки. PDF created with pdfFactory Pro trial version www.pdffactory.com 41 ПРОЦЕДУРА WRITE. Обеспечивает вывод информации в текстовый файл или передачу ее на логическое устройство. Формат обращения: WRITE(<ф.п.>,<сп.вывода>) или WRITE(<сп.вывода>) Здесь <сп.вывода> - список вывода: последовательность из одного или более выражений типа CHAR, STRING, BOOLEAN, а также любого целого или вещественного типа. Файловая переменная <ф.п.>, если она указана, должна быть предварительно описана как переменная типа TEXT и связана с именем файла или логическим устройством процедурой ASSIGN. Если файловая переменная отсутствует, подразумевается вывод в стандартный файл OUTPUT, который обычно связан с экраном ПК. Любой элемент списка вывода может иметь форму: OutExpr [ : MinWidth [ : DecPlaces ] ] Здесь OutExpr - выводимое выражение; MinWidth, DecPlaces - выражение типа WORD (квадратные скобки означают возможность отсутствия заключенных в них параметров). Подпараметр MinWidth, если он присутствует, указывает минимальную ширину поля, в которое будет записываться символьное представление значения OutExpr. Если символьное представление имеет меньшую длину, чем MinWidth, оно будет дополнено слева пробелами, если - большую длину, то подпараметр MinWidth игнорируется и выводится необходимое число символов. Подпараметр DecPlaces задает количество десятичных знаков в дробной части вещественного числа. Он может использоваться только совместно с MinWidth и только по отношению к выводимому выражению одного из вещественных типов. Если ширина поля вывода не указана, соответствующий параметр выводится вслед за предыдущим без какого-либо их разделения. Символы и строки передаются выводному файлу без изменений, но снабжаются ведущими пробелами, если задана ширина поля вывода и эта ширина больше требуемой для вывода. При выводе логических выражений в зависимости от их значения выводятся строки TRUE или FALSE. (Ввод логическиих констант процедурами READ или READLN не предусмотрен ). Вещественные числа выводятся в экспоненциальном формате, если не указан подпараметр DecPlaces, в противном случае выбирается формат представления числа с фиксированной точкой. Экспоненциальный формат представляет вещественное число в виде: _s#.##############E*####, где _ -пробел; PDF created with pdfFactory Pro trial version www.pdffactory.com 42 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 с дисковыми файлами и логическими устройствами. Дело в том, что для логического устройства невозможно предвидеть, каким будет результат PDF created with pdfFactory Pro trial version www.pdffactory.com 43 чтения очередного символа. Поэтому при работе с логическим устройством функция EOLN возвращает TRUE, если последним считанным с устройства символом был EOLN или EOF, в то время как при чтении с диска TRUE возвращается в случае, если следующим считываемым символом будет EOLN или EOF.Аналогичное различие наблюдается и в функции EOF: для логического устройства TRUE возвращается в случае, если последним символом был EOF, а при чтении с диска - если следующим считываемым символом будет EOF. Иными словами, функции тестируют соответстствующие признаки для логического устройства после очередного чтения, а для файла - перед чтением. ЛОГИЧЕСКАЯ ФУНКЦИЯ SEEKEOLN |