Assign(Input, 'CON'), Reset(Input)
Assign(0utput, 'CON');Rewrite(Output);
После этого все процедуры записи Write и чтения Read работают соответственно с файлами Output и Input.
LPT1, LPT2 и LPT3 - соответствуют трем возможным именам устройств печати, которые поддерживаются операционной системой. Если к компьютеру подсоединено одно печатающее устройство, то используется символическое имя 'LPT1' либо его синоним - 'PRN'. Устройство печати является устройством вывода, поэтому после назначения его файловой переменной типа Text с помощью процедуры Assign открытие такого файла для последующей записи должно осуществляться процедурой Rewrite. И хотя в языке предусмотрен соответствующий модуль Printer, стандартно поддерживающий вывод на печать, мы можем привести здесь корректную последовательность команд, позволяющую добиться этого в рамках модуля System.
Var
Lst : text;
Begin
Assign(Lst, ‘LPT1’);
Rewrite(Lst);
Write(Lst, 'Печать из модуля System');
close(Lst);
End.
В результате на печать будет выдано сообщение "Печать из модуля System".
СОМ1, COM2 - соответствуют двум устройствам последовательного ввода-вывода, т.е двум последовательным портам связи, которые используются для обмена данными между компьютерами Синонимом имени устройства 'СОМ' может выступать символическое имя 'AUX'
NUL - нулевое устройство, для которого вывод означает "путь в никуда", а при попытке чтения немедленно возникает ситуация конца файла, это устройство очень часто используется с уровня команд операционной системы для запрещения вывода сообщений на экран. Так, например, команда
C:>DIR выдает список файлов текущего каталога на экран, а команда
c:>dir > NUL ничего не выдает на экран, хотя и производит считывание списка файлов с диска.
В языке Паскаль использование такого устройства по символическому имени приводит к подобному эффекту и станет более ясным после того, как мы познакомимся с другими файловыми процедурами.
CRT - устройство текстового ввода-вывода, не поддерживаемое операционной системой и аналогичное по действию устройству CON. Вследствие лучшей реализации это устройство помимо стандартных функций устройства CON поддерживает много полезных дополнительных функций.
Интерпретация любого внешнего устройства как внешнего файла приводит к единообразию процесса передачи данных. На практике это приводит к поразительным эффектам, при перенаправлении потоков передачи данных, а также дает возможность использовать стандартный программный аппарат обработки файлов Эта стратегия получила свое полное завершение в Unix-подобных операционных системах.
Итак, процедура Assign позволяет связать любую файловую переменную в программе с конкретным внешним файлом или устройством. Далее рассмотрим общие операции, которые можно производить над всеми внешними файлами независимо от их специфики.
2. Открытие файла – Reset, Rewrite.
Для работы с файлом после его объявления прежде всего необходимо его открыть. В языке Паскаль предусмотрены для этого две процедуры:
Reset(f : file); - открывает существующий файл;
Rewrite(f : file); - создает и открывает новый файл.
При описании обеих процедур параметр <file> означает файловую переменную любого типа. Открытие внешнего файла с помощью процедуры Reset в случае его отсутствия на диске может привести к ошибке при выполнении программы. Подобные ошибочные ситуации в операциях ввода-вывода позволяет отслеживать специальная функция IOresult.
Пример. Стандартное открытие файла.
Assign(f,’c:\TSS\TSS85\Vovchik.txt’);
Reset(f);
В Pascal При назначении файловой переменной пустой строки происходит автоматическая ссылка на стандартный файл ввода, что в модуле System соответствует устройству con.С открытием такого файла появляется возможность ввода данных с клавиатуры.
Операционная система устанавливает каждому открываемому файлу так называемыйобработчик файлов с определенным номером. Этот обработчик осуществляет операции обмена данными через буфер ввода-вывода. Определение таких обработчиков и их количество на сеанс работы устанавливается при загрузке операционной системы с помощью специальной команды <files>, включенной в файл конфигурации CONFIG.SYS. Например, команда files = 15 в файле config.sys задает возможность одновременной работы с 15 пользовательскими файлами, определяет соответствующее количество обработчиков файлов и резервирует для этого необходимые ресурсы.
Имеются некоторые отличия в использовании процедуры Reset при открытии различных типов файлов. В отношении текстовых файлов (тип text) действие процедуры означает открытие файла только для чтения. Для нетипизированных файлов в описание процедуры добавляется еще один параметр RecSize типа word, который устанавливает длину записи для функций обмена с файлом. Процедура Reset для нетипизированного файла имеет вид:
Reset(f : file; RecSize : word);
Процедура Rewrite создает и открывает новый файл. Использование этой процедуры требует особого внимания. При попытке создать и открыть новый файл с именем уже существующего на диске набора данных действие процедуры Rewrite сведется к удалению этого набора и созданию нового пустого файла с тем же именем. На практике это приводит к потере информации. Реальный выход в таких ситуациях заключается в предварительном создании резервных копий тех файлов, над которыми могут производиться подобные критические действия.
Rewrite(f);
При открытии новых нетипизированных файлов для задания длины записи в описание процедуры Rewrite добавляется дополнительный параметр RecSize типа word. В этом случае процедура имеет вид:
Rewrite(f : file; RecSize : word);
Если процедура Rewrite используется для текстового файла, то к открываемому новому набору данных в дальнейшем могут быть применимы только операции записи.
3. Закрытие файла - Close.
Операция закрытия файла является логическим окончанием работы с любым открытым файлом. Для этого служит процедура
Close(f : file); {for Pascal}
CloseFile(f : file); {for Delphi}
Использование процедуры Close позволяет устранить связь файловой переменной с внешним файлом,установленную с помощью процедуры Assign. Выражаясь языком операционной системы, можно сказать, что после обращения к процедуре Close выделенный для данного файла обработчик освобождается для других работ. Этим продиктовано требование обязательного закрытия файла после окончания работы с ним.
Пример. Полная цепочка команд для создания простого текстового файла с именем SVETA.TXT для Pascal:
Var f:text;
Begin
Assign(f, 'Sveta.ТХТ');
ReWrite(f);
Write(f, 'Простой текстовый файл');
Close(f);
End.
4. Переименование и удаление файла – Rename, Erase.
К языковым средствам обслуживания наборов данных необходимо отнести процедуры переименования и удаления неоткрытых файлов. Использование этих процедур не зависит от типа файла.
Процедура Rename(f : file; NewName : string); переименовывает неоткрытый файл f любого типа. Новое имя задается строкой NewName.
Процедура Erase(f : file); удаляет неоткрытый внешний файл любого типа, задаваемый переменной f.
Обе процедуры нельзя использовать для уже открытых файлов. В противном случае могут возникнуть нежелательные последствия со стороны операционной системы. Единственным стандартным шагом перед использованием процедур является установка связи между внешним файлом с конкретным именем и файловой переменной. Операции удаления и переименования осуществляются только для реально существующих файлов, иначе возникает ошибка выполнения программы.
Пример для Pascal. Удаление и переименование файла.
Var
f : file;
Ch . char;
St : string;
Begin
Write('Введите имя файла : ');
Readln(St); { чтение имени }
Assign(f, St); { назначить имя файловой переменной }
Wгite('Удалить файл (У), Переименовать(П), Выход(В)');
Readln(Ch);
Case Ch of
'У,'у' : Erase(f); { удаление файла }
'П','п' : begin
Write(‘Введите новое имя файла : ');
Readln(St);
Rename(f, St); { переименование файла }
end;
'В','в' : halt(l);
end; {case}
End.
Типизированные файлы.
К типизированным файлам относятся файлы строго определенного типа. Стандартное задание в программе такой файловой переменной осуществляется следующим образом:
Type
FileRec = record
…
end;
Var Ft : file of FileRec;
1. Длина записи.
Если в текстовых файлах содержимое рассматривается как наборы символов, подготовленные специальным образом с учетом общепринягтых соглашений о представлении текстовой информации, то в типизированных файлах их содержимое рассматривается как последовательность записей определенного типа. Единицей измерения такого набора данных является сама запись. Длина записи определяется как Sizeof(FileRec).
2. Позиционирование записи в файле.
Процедура Seek(f; NumRec: Longint) устанавливает текущую файловую переменную f на запись с номером NumRec; f - файловая переменная для типизированных и нетипизированных наборов данных. При открытии типизированного файла текущая позиция для работы с ним установлена на начало первой записи, которая по принятым соглашениям имеет номер 0, т.е. номер физической записи на единицу меньше номера логической записи. Это небольшое несоответ-
ствие в номерах может служить причиной возникновения ошибок чтения-записи, что в результате может привести к нарушению целостности важной информации. Положение усугубляется тем, что неверное позиционирование на запись с помощью процедуры Seek, как правило, не приводит к каким-либо видимым ошибкам ввода-вывода, на которые всегда можно отреагировать. Исключение составляют ситуации, когда нет доступа к файлу, файл не открыт или назначено позиционирование на несуществующую запись, такие ситуации обрабатываются с помощью функции lOresult.
Типизированные файлы ( в отличие от текстовых) позволяют организовать работу в режиме чтения-записи. Эта возможность играет решающую роль при определении, каким типам файлов отдать предпочтение для большинства прикладных задач. Информация в типизированных наборах данных представлена в том же виде, как и в памяти машины во время выполнения программы, поэтому не надо отслеживать управляющие последовательности типа конец строки или возврат каретки. Идентификация соответствия типа записи и конкретной физической информации требует незначительной части ресурсов системы.
3. Вспомогательные функции FilePos и File Size.
Для работы с файлами прямого доступа используются две специальные функции:
FilePos(F) : Longint - возвращает для файла F текущую файловую позицию (номер записи, на которую она установлена) в виде значения типа Longint;
FileSize(F) : Longint - возвращает для файла F его размер (количество записей) в виде значения типа Longint.
Для пустого файла вызов FileSize возвращает значение 0. Локализация ошибок при обращении к внешним носителям для обоих функций производится через lOresult.
Для того чтобы очередная запись могла быть записана в конец типизированного файла, необходимо перевести текущую файловую позицию в конец файла. Когда создается новый файл, это происходит автоматически после формирования каждой очередной записи. Если файл ухе создан и файловая позиция, установленная по Seek(), находится где-нибудь в начале файла (FilePos(F) < FileSize(F)), то в конец файла ее позволяет перевести вызов Seek(F, FileSize(F));
В каждом файле число логических и физических записей совпадает, а при позиционировании номер физической записи на единицу меньше номера логической записи.
Пример для Pascal:
Type Klient= record
Number : integer; { номер}
Marka : string[20]; { марка автомобиля }
FIO : string[40]; { фамилия,инициалы владельца }
adres : string[88] { адрес владельца }
end;
Var M : Klient;
F : file of Klient;
Begin
With M do
begin
Number :=43;
Marka :=’Запорожец’;
FIO := ‘Ильин М.И.';
Adres :=’ул. Болтунов, 5'
end;
Assign(f,’RecKl.ttt’);
Rewrite(f);
Write(f);
Close(f);
End.
Контрольные вопросы
1. Что такое запись и из чего она состоит?
2. Какие есть способы обращения к полям записи?
3. Перечислите основные действия при работе с файлами.
4. Что такое файловая переменная и как ее использовать?
5. Обязательно ли задавать полное имя открываемого файла (со всем путем к нему)?
6. В чем отличие типизированного файла от нетипизированного?
7. В чем приемущество нетекстовых файлов от текстовых? В каких случаях удобно исползовать те и другие?