Работа с файлами
Тип-файл представляет собой последовательность компонент одного типа, расположенных на внешнем устройстве (например, на диске).
Любой файл имеет 3 характерные особенности:
- у него есть имя (что позволяет программе работать одновременно с несколькими файлами);
- он содержит компоненты одного типа (компоненты могут быть любого типа, за исключением самого типа-файла, то есть нельзя создать "файл файлов")
- длина вновь создаваемого файла никак не оговаривается при его объявлении и ограничивается только емкостью внешней памяти и возможностями операционной системы.
Для задания типа-файла следует использовать зарезервированные слова File и Of, после чего указать тип компонент файла.
Пример:
Type
N = File Of Integer; {Тип-файл целых чисел}
C = File Of Char; {Тип-файл символов}
Есть заранее определенный в Паскале тип файла с именем Text. Файлы этого типа называют текстовыми.
Введя файловый тип, можно определить и переменные файлового типа:
Var
F1 : N;
F2 : C;
F3 : Text;
Тип-файл можно описать и непосредственно при введении файловых переменных:
Var
Z : File Of Word;
Файловые переменные имеют специфическое применение. Над ними нельзя выполнять никаких операций (присваивать значение, сравнивать и т.д.). Их можно использовать лишь для выполнения операций с файлами (чтение, запись и т.д.).
Элементы файла считаются расположенными последовательно, то есть так же, как элементы линейного массива. Отличие же состоит в том, что, во-первых, размеры файла могут меняться, во-вторых, способ обращения к элементам совсем другой: невозможно обратиться к произвольному элементу файла; элементы его просматриваются только подряд от начала к концу, при этом в каждый момент времени доступен только один элемент. Можно представить себе, что для каждого файла существует указатель, показывающий в данный момент на определенный компонент файла. После проведения операции чтения или записи указатель автоматически передвигается на следующий компонент.
Assign(<Имя файловой переменной>,<Имя файла>);
Перед использованием файловой переменной она должна быть связана с конкретным внешним файлом с помощью вызова процедуры Assign. Внешним файлом обычно является поименованный файл на диске, но он также может представлять собой устройство, как например, клавиатуру или дисплей. Во внешних файлах сохраняется записанная в файл информация, или они служат источниками информации, которая считывается из файла.
Имя файла задается либо строковой константой, либо через переменную типа String. Имя файла должно соответствовать правилам работающей в данный момент операционной системы. Если строка имени пустая, то связь файловой переменной осуществляется со стандартным устройством ввода-вывода (как правило - с консолью).
Когда связь с внешним файлом установлена, для подготовки ее к операции ввода или вывода файловая переменная должна быть "открыта". Существующий файл можно открыть с помощью процедуры Reset (указатель текущей компоненты файла настраивается на начало файла; если физического файла, соответствующего файловой переменной не существует, то возникает ситуация ошибки ввода-вывода):
Reset(<Имя файловой переменной>);
а новый файл можно создать и открыть с помощью процедуры Rewrite (открывается новый пустой файл для записи, ему присваивается имя, заданное процедурой Assign. Если файл с таким именем уже существует, то он уничтожается):
Rewrite(<Имя файловой переменной>);
Для текстовых файлов может быть использована еще одна процедура открытия файла (указатель файла устанавливается в его конец)
Append(<Имя файловой переменной>);
Текстовые файлы, открытые с помощью процедуры Reset, доступны только для чтения, а текстовые файлы, открытые с помощью процедуры Rewrite и Append, доступны только для записи. Типизированные и нетипизированные файлы всегда допускают как чтение, так и запись, независимо от того, были они открыты с помощью процедуры Reset или с помощью процедуры Rewrite.
Когда программа завершит обработку файла, он должен закрываться с помощью стандартной процедуры Close. После полного закрытия файла, связанный с ним внешний файл обновляется. Затем файловая переменная может быть связана с другим внешним файлом.
Close(<Имя файловой переменной>);
Внимание: Это требование обязательно должно соблюдаться для файла, в который производилась запись !
Последовательный и прямой доступ
Обычно доступ к файлам организуется последовательно, то есть, когда элемент считывается с помощью стандартной процедуры Read или записывается с помощью стандартной процедуры Write, текущая позиция файла перемещается к следующему по порядку элементу файла. Однако к типизированным и нетипизированным файлам можно организовать прямой доступ с помощью стандартной процедуры Seek (которая перемещает текущую позицию файла к заданному элементу):
Seek(<Имя файловой переменной>, <Номер компоненты>);
Текущую позицию в файле и текущий размер файла можно определить с помощью стандартных функций FilePos (возвращает значение типа LongInt, содержащее порядковый номер компоненты, которая будет обрабатываться следующей операцией ввода-вывода) и FileSize (возвращает значение типа LongInt, которое содержит количество компонентов файла):
FilePos(<Имя файловой переменной>);
FileSize(<Имя файловой переменной>);
Внимание: Функции прямого доступа неприменимы к текстовым файлам !
Чтение и запись
Теперь рассмотрим непосредственную организацию чтения и записи.
Любой файл представляет собой линейную последовательность элементов, каждый из которых имеет сложный тип (или тип записи) файла. Каждый элемент файла имеет номер. Первый элемент файла считается нулевым элементом.
Для ввода информации из файла, открытого для чтения, используется оператор Read. Правда, в его формате и использовании есть некоторые изменения:
Read(<Имя файловой переменной>, <Список ввода>);
Происходит считывание данных из файла в переменные, имена которых указаны в списке ввода. Переменные должны быть того же типа, что и компоненты файла.
Вывод информации производит, как можно догадаться, оператор:
Write(<Имя файловой переменной>, <Список вывода>);
Данные из списка вывода заносятся в файл, открытый для записи.
Любопытно, что вывод данных на монитор и ввод с клавиатуры в языке Паскаль тоже являются действиями с файлами. Они даже имеют свои предопределенные файловые переменные текстового типа: Output и Input соответственно. Переменная Output всегда открыта для записи, Input - для чтения. Если не указывать файловые переменные в операторах ввода-вывода, то в случае записи по умолчанию выбирается файл Output, в случае чтения - Input.
Любой файл конечен и продолжать чтение из него информации можно лишь до определенного предела. Как этот предел установить? Проверить, окончен ли файл, можно вызовом стандартной логической функции:
Eof(<Имя файловой переменной>)
Она возвращает значение True, если файл окончен, и False - в противном случае.