Основы алгоритмизации и программирования. Часть четвертая. Файловая система Turbo Pascal. Асламова В.С - 27 стр.

UptoLike

53
var
Fr, Fw: File; {файловые переменные}
Re, Wr: Word; {переменные контроля}
Destin:........; { приемник при чтении }
Source: .......; {источник при записи}
BEGIN
BlockRead (Fr, Destin, 3, Re);
if Re <>3 then {обработка ошибки чтения}
BlockWrite (Fw, Source, 4, Wr);
if Wr <>4 then {обработка ошибки записи}
end
.
Если в вызове BlockRead последний параметр не указан, то невозмож-
ность считать заданное число блоков вызовет ошибку ввода - вывода и
остановку программы.
Процедуры BlockRead и BlockWrite не имеют списков ввода и вывода,
поскольку не определен тип компонента файла. Взамен их в вызовах присут-
ствуют бестиповые переменные. Адрес начала переменной в памяти
соответствует адресу области
памяти, начиная с которого заданное количест-
во байт будет выведено в файл при записи или помещено в память из файла
при чтении. Передавая переменную процедуре, мы всегда тем самым переда-
ем адрес ее содержимого, точнее, первого байта ее значения. Если
переменная Хмассив,
var
X:Array [1..10] of...;
то вызов BlockWrite или BlockRead с ней будет
принимать за точку начала
отсчета блока первый элемент массива. Можно более явно указать в вызове
начало блока как Х[1]. Но если подставить Х[5], то отсчет блока будет вес-
тись уже сразу с пятого элемента массива.
Особенно осторожно надо будет обращаться со ссылками при подста-
новке их в BlockRead и BlockWrite. Ссылки должны быть
разыменованы, с
тем, чтобы показывать на данные, а не на место в памяти, где хранится сама
ссылка. Так, если определена ссылочная переменная Р:
TYPE
Dim = Array [0..999] of Real; {массив}
var
54
Р : ^Dim, {ссылка на массив}
f :File; {бестиповый файл}
то после создания динамического массива P^ вызовом процедуры New(P) и
его заполнения, он может быть записан в файл f следующим образом:
Assign (f,
DIMFILE.DAT); {связывание f c диском}
Rewrite (f, SizeOf (Dim)); {открытие f для записи}
BlockWrite (f, P^, l); {запись массива в файл по 1 байту}
{ссылка Р разыменована!}
Close (f); {закрытие файла f}
Если ошибочно написать Р вместо Р^ то процедура сработает, но со-
хранит в файле кусок памяти, начиная с Addr(P^), который вовсе не равен
адресу динамического массива Addr(P^)!
Чтобы прочитать впоследствии записанный массив из файла,
нужно
развернутьнаправление вывода данных:
{Место под массив P^ должно быть зарезервировано!}
New (Р);
Assign (f,
DIMFILE.DAT); {связывание f c диском}
Reset (f, SizeOf (Dim)); {открытие f для чтения}
BlockRead (f, P^,l); {чтение массива из файла по 1 байту}
{Ссылка Р разыменована!}
Close (f); {закрытие файла f}
Перед чтением блока в динамическую переменную (здесь: Р^), она
должна быть корректным образом создана (через вызов New либо GetMen
или присвоением значения адреса), иначе последствия будут непредсказуе-
мы.
Блочный способ работы с файлами весьма
эффективен по времени, и
если программа использует крупные массивы предварительно вычисляемых
констант, то может оказаться более выгодным вынести их вычисления в от-
дельную программу, которая затем сохранит их на диске, а в расчетной
программе просто вставить операторы блочного чтения уже рассчитанных
значений. В таких случаях можно даже сыграть на особенностях компилятора
Турбо Паскаля. Обычно при компиляции программ память под статические
массивы (но не под динамические) отводится в порядке их следования в опи-
сании. Так, если описаны
     var                                                                          Р : ^Dim,                           {ссылка на массив}
     Fr, Fw: File;                {файловые переменные}                           f :File;                            {бестиповый файл}
     Re, Wr: Word;        {переменные контроля}
     Destin:........;              { приемник при чтении }                   то после создания динамического массива P^ вызовом процедуры New(P) и
     Source: .......;              {источник при записи}                     его заполнения, он может быть записан в файл f следующим образом:
     BEGIN
                                                                                    Assign (f, ′DIMFILE.DAT′);        {связывание f c диском}
                                                                                  Rewrite (f, SizeOf (Dim));          {открытие f для записи}
            BlockRead (Fr, Destin, 3, Re);
            if Re <>3 then                 {обработка ошибки чтения}                  BlockWrite (f, P^, l);          {запись массива в файл по 1 байту}
            BlockWrite (Fw, Source, 4, Wr);                                                                           {ссылка Р разыменована!}
            if Wr <>4 then                 {обработка ошибки записи}              Close (f);                          {закрытие файла f}
                                                                                   Если ошибочно написать Р вместо Р^ то процедура сработает, но со-
     end.                                                                    хранит в файле кусок памяти, начиная с Addr(P^), который вовсе не равен
                                                                             адресу динамического массива Addr(P^)!
      Если в вызове BlockRead последний параметр не указан, то невозмож-
                                                                                   Чтобы прочитать впоследствии записанный массив из файла, нужно
ность считать заданное число блоков вызовет ошибку ввода - вывода и
                                                                             “развернуть” направление вывода данных:
остановку программы.
                                                                                   {Место под массив P^ должно быть зарезервировано!}
      Процедуры BlockRead и BlockWrite не имеют списков ввода и вывода,
                                                                                   New (Р);
поскольку не определен тип компонента файла. Взамен их в вызовах присут-
                                                                                      Assign (f, ′DIMFILE.DAT′); {связывание f c диском}
ствуют бестиповые переменные. Адрес начала переменной в памяти
                                                                                         Reset (f, SizeOf (Dim)); {открытие f для чтения}
соответствует адресу области памяти, начиная с которого заданное количест-
                                                                                         BlockRead (f, P^,l);     {чтение массива из файла по 1 байту}
во байт будет выведено в файл при записи или помещено в память из файла
                                                                                                                  {Ссылка Р разыменована!}
при чтении. Передавая переменную процедуре, мы всегда тем самым переда-
                                                                                         Close (f);               {закрытие файла f}
ем адрес ее содержимого, точнее, первого байта ее значения. Если
переменная Х – массив,                                                             Перед чтением блока в динамическую переменную (здесь: Р^), она
      var                                                                    должна быть корректным образом создана (через вызов New либо GetMen
         X:Array [1..10] of...;                                              или присвоением значения адреса), иначе последствия будут непредсказуе-
                                                                             мы.
то вызов BlockWrite или BlockRead с ней будет принимать за точку начала
                                                                                   Блочный способ работы с файлами весьма эффективен по времени, и
отсчета блока первый элемент массива. Можно более явно указать в вызове
                                                                             если программа использует крупные массивы предварительно вычисляемых
начало блока как Х[1]. Но если подставить Х[5], то отсчет блока будет вес-
                                                                             констант, то может оказаться более выгодным вынести их вычисления в от-
тись уже сразу с пятого элемента массива.
                                                                             дельную программу, которая затем сохранит их на диске, а в расчетной
      Особенно осторожно надо будет обращаться со ссылками при подста-
                                                                             программе просто вставить операторы блочного чтения уже рассчитанных
новке их в BlockRead и BlockWrite. Ссылки должны быть разыменованы, с
                                                                             значений. В таких случаях можно даже сыграть на особенностях компилятора
тем, чтобы показывать на данные, а не на место в памяти, где хранится сама
                                                                             Турбо Паскаля. Обычно при компиляции программ память под статические
ссылка. Так, если определена ссылочная переменная Р:
                                                                             массивы (но не под динамические) отводится в порядке их следования в опи-
      TYPE
                                                                             сании. Так, если описаны
      Dim = Array [0..999] of Real;     {массив}
         var
                                     53                                                                          54