Чтобы прочитать впоследствии записанный массив из файла, нужно «развернуть» направление вывода данных:
{ Место под массив P^ должно быть зарезервировано! }
New( Р );
Assign( f, 'DIMFILE.DAT' ); { связывание f с диском }
Reset( f, SizeOf( Dim ) ); { открытие f для чтения }
BlockRead( f, P^, 1 ); { чтение массива из файла}
{ Ссылка Р разыменована! }
Close( f ); { закрытие файла f }
Перед чтением блока в динамическую переменную (здесь: P^) она должна быть корректным образом создана (через вызов New либо GetMem или присвоением значения адреса), иначе последствия будут непредсказуемыми.
Блочный способ работы с файлами весьма эффективен по времени, и если программа использует крупные массивы предварительно вычисляемых констант, то может оказаться более выгодным вынести их вычисления в отдельную программу, которая затем сохранит их на диске, а в расчетной программе просто вставить операторы блочного чтения уже рассчитанных значений. В таких случаях можно даже сыграть на особенностях компилятора Турбо Паскаля. Обычно при компиляции программ память под статические массивы (но не под динамические) отводится в порядке их следования в описании. Так, если описаны
VAR
A, B, C : Array [1..2000] of Real;
то их элементы выстраиваются в одну сплошную цепочку. Иными словами:
Addr(B) = Addr(A) + SizeOf(A),
Addr(C) = Addr(B) + SizeOf(B).
(Это верно не только для массивов, но и для любых статических структур, кроме объектов: память в пределах блока описания переменных отводится последовательно по мере их следования.)
- 254 -
Используя этот факт, можно записать или считать блоком сразу несколько структур данных, приняв за начало блока первую из них:
Assign( f, 'ABC.DAT' );
Rewrite( f, SizeOf(A) ); { открыть f и записать в }
BlockWrite( f, A, 3); { него три блока сразу }
Close( f );
или
Reset( f, SizeOf(A) ); { открыть f и считать из }
BlockRead( f, A, 3); { него три блока сразу } Close( f );
Другой, более специфичной областью применения бестиповых файлов является работа с системными областями памяти ПЭВМ, в том числе с видеопамятью. Одной из иллюстраций этого является, например, запись текстовых и графических изображений, рассматриваемая в разд. 20.4 и 22.3.
12.9. Последовательный и прямой доступ к файлам
Файл — это последовательная структура данных. И естественным способом доступа к компонентам файла является последовательный доступ. После открытия файла он «ждет» чтения или записи первого компонента. После каждого очередного обращения к файлу он готов выдать или принять очередной по счету компонент. В данном случае возможно только косвенно управлять последовательностью чтения или записи.
Пусть нужно прочитать из файла f пятый элемент и записать его в переменную V соответствующего типа. Это можно сделать, считав «впустую» четыре первых значения:
Reset( f ); { файл открыт для чтения первого компонента }
for i:=1 to 5 do Read ( f, v );
Reset(f); { переустановка снова на первый компонент }
В V останется лишь последнее, пятое, значение из файла. Это, конечно, не самое удачное решение проблемы прямого доступа, т.е. доступа сразу к тому компоненту, который нас интересует. Гораздо лучше будет использовать встроенные процедуры и функции Турбо Паскаля для прямого доступа к компонентам файла (табл. 12.4).
- 255 -
Функции и процедуры | Назначение |
FileSize(VAR : f) : LongInt | Возвращает число записей компонентов или блоков в открытом файле f |
FilePos(VAR f) : LongInt | Функция возвращает номер записи компонента или блока в открытом файле f, предшествующий тому, который будет считан или записан последующей операцией ввода-вывода |
Seek(VAR f; W : LongInt) | Устанавливает текущим компонентом (блоком) в открытом файле f компонент с номером N, отсчитанным от нулевого. Назначенный компонент будет считан или записан последующей операцией ввода-вывода |
Truncate(VAR f) | Отсекает часть открытого файла f, начиная с того компонента, который был бы считан последующей операцией ввода, и подтягивает на ее место конец файла |
Внимание! Процедуры и функции прямого доступа применимы только к типизированным и бестиповым файлам, но не к текстовым.
В эту же таблицу можно было бы включить и функцию EOF(VAR f), описанную ранее в этой главе как общую для всех файлов.