Программирование в среде Турбо Паскаль (Поляков, Круглов) - страница 163

TYPE

Dim = Array [0..999] of Real; { массив }

VAR

P : ^Dim; { ссылка на массив }

f : File; { бестиповый файл }

то после создания динамического массива P^ вызовом процедуры New(Р) и его заполнения, он может быть записан в файл f следующим образом:

- 253 -

Assign( f, 'DIMFILE.DAT' ); { связывание f с диском }

Rewrite( f, SizeOf( Dim ) ); { открытие f для записи }

BlockWrite( f, Р^, 1 ); { запись массива в файл }

{ Ссылка P разыменована! }

Close( f ); { закрытие файла f }

Если ошибочно написать P вместо P^, то процедура сработает, но сохранит в файле кусок памяти, начиная с Addr(P), который вовсе не равен адресу динамического массива Addr(P^)!

Чтобы прочитать впоследствии записанный массив из файла, нужно «развернуть» направление вывода данных:

{ Место под массив 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 );