Типизированные файлы в Pascal
Обновлено: 03.05.2026
В Pascal при определении переменной типизированного файла указывается тип компонентов, из которых он будет состоять:
var имя_переменной: file of тип_компонентов_файла
Например, из выражения var f: file of Real; следует, что элементами файла, связанного с переменной f, будут числа типа real, занимающие по 8 байт каждое.
Типизированные файлы являются файлами произвольного доступа, так как содержащиеся в них данные представляют собой последовательность компонентов одного типа, что дает возможность точно отсчитывать от начала позицию каждого и обращаться к этому элементу. Для таких перемещений используется файловый указатель. Из-за возможности произвольного доступа к элементам типизированный файл несколько напоминает одномерный массив.
Произвольный доступ к элементам позволяет открывать типизированный файл и для чтения и для записи как с помощью процедуры reset, так и rewrite (а не только для чтения или только для записи как в случае текстовых файлов). Так если файл уже существует, и вы хотите сохранить в нем имеющиеся данные, но изменить их или что-то добавить, то открывать файл надо через reset. Если вы создаете новый файл или полностью перезаписываете существующий, то используется rewrite. При этом имеется возможность считывать и изменять данные, которые были записаны после открытия файла.
При открытии файла с ним связывается текущий указатель файла, который позиционируется на его первый элемент. Оперировать можно только тем элементом файла, на который ссылается указатель файла. При чтении или записи элемента файла происходит автоматическое перемещение указателя на следующий элемент.
Чтение из типизированного файла производится только с помощью read, а запись в него — только командой write. Ввод-вывод с суффиксом "ln" не используется.
Создадим типизированный файл и запишем в него числа, вводимые с клавиатуры. В качестве условия завершения ввода будем использовать число меньше нуля:
var a: file of integer; n: integer; begin assign(a, 'numbers'); rewrite(a); read(n); while n > -1 do begin write(a, n); read(n); end; close(a); end.
Мы используем rewrite, а не reset, потому что если файл numbers еще не существует, то создать его можно только так. После выполнения программы мы не сможем открыть файл numbers в текстовом редакторе, потому что он содержит двоичные данные. Если вам все-таки хочется посмотреть, что внутри, в Linux это можно сделать в терминале с помощью команд hexdump и xxd:
pu@home:~/pas_theory/30_type$ hexdump numbers 0000000 0028 0000 0020 0017 0009 000f 0041 000000e
Теперь напишем программу, которая читает типизированный файл и выводит данные из него на экран:
var a: file of integer; n: integer; begin assign(a, 'numbers'); reset(a); while not eof(a) do begin read(a, n); write(n, ' '); end; writeln; close(a); end.
Пример вывода:
40 0 32 23 9 15 65
Поскольку типизированный файл был открыт на чтение, мы можем также дописывать в него данных. Если файл уже был прочитан, то указатель находится в его конце.
Чтобы узнать, на каком элементе располагается указатель файла, используют функцию FilePos:
FilePos(файловая_переменная)
Элементы типизированного файла нумеруются с нуля, поэтому число 65 в примере выше будет иметь индекс 6, а выражение writeln(filePos(a)), расположенное после цикла, выведет на экран 7. В эту позицию будет записано, например, число 13, если мы выполним write(a, 13).
Для изменения местоположения указателя используется процедура seek с таким синтаксисом:
Seek(файловая_переменная, номер_элемента)
Второй параметр имеет тип LongInt и задает номер элемента, на который должен переместиться указатель файла. При выполнении следующих команд число 32 в примере вывода выше перезапишется на 13, после чего курсор снова вернется в начало файла:
seek(a, 2); write(a, 13); seek(a, 0);
Обратите внимание, в произвольном месте файла элементы можно только заменять, но не вставлять или удалять. Для таких действий файл должен быть перезаписан. Добавлять данные вы можете только в конец файла.
Представим, что мы не хотим читать файл, а будем сразу добавлять данные с конца. Первым делом нам понадобится функция FileSize, которая возвращает количество элементов типизированного файла и имеет следующий синтаксис:
FileSize(файловая_переменная)
Возвращаемое значение имеет тип LongInt. Заметим, когда файл читался, функция eof(файловая_переменная) возвращала значение True, если текущий указатель располагался на признаке конца файла, то есть выполнялось равенство FilePos(файловая_переменная) = FileSize(файловая_переменная).
Так если в файле 7 чисел, то writeln(fileSize(a)) это число и выведет. Одновременно оно будет индексом элемента, добавляемого в конец. Поэтому перемещение курсора в конец файла и дозапись в него могут выглядеть так:
seek(a, fileSize(a)); read(n); while n > -1 do begin write(a, n); read(n); end;
Задания для дополнительной или самостоятельной работы:
Элементами типизированного файла могут быть и записи. Определите запись Subscriber, содержащую поля name (имя) и mail (почта). Объявите переменную типа Subscriber, а также файловую, в которой элементы такого же типа. Первая программа должна создавать файл и записывать в него данные трех человек. Вторая программа должна отображать на экране уже имеющиеся в файле записи, позволять добавлять новых людей и менять данные существующих.