Работа с файлами данных в Pascal

Автор: Пользователь скрыл имя, 28 Декабря 2011 в 12:54, реферат

Описание работы

Надо заметить, что физически единой эта область данных вовсе не является: файл обычно состоит из целого набора так называемых кластеров (участков диска фиксированного для операционной системы размера), которые разбросаны по диску тем прихотливее, чем чаще мы стираем и записываем на него информацию.
Вообще, система окажется наиболее производительной, если кластеры файла будут идти не подряд, а с неким постоянным интервалом: пока система "переварит" данные с одного кластера, диск как раз успеет повернуться до другого.

Работа содержит 1 файл

Документ Microsoft Office Word (4).docx

— 64.43 Кб (Скачать)

Операторы Write (F, x1, x2, ...) и Writeln (F, x1, x2, ...) записывают в  файл F значения переменных x1, x2, ... точно  так же, как это делают операторы Write и Writeln для консольного вывода. Аргументы могут иметь любой  арифметический тип и для них  действуют те же правила форматирования:

  • Write(F, x:n) - для строчных и символьных значений (n - число позиций, отводимых под значение);
  • Write(F, x:n) - для целых значений (n - число цифр);
  • Write(F, x:n:m) - для вещественных в обычной форме (n - общее количество позиций, m - число знаков после запятой);
  • Write(F, x:n) - для вещественных в экспоненциальной форме (n - длина поля вывода, n>=8).

При n>0 выравнивание производится по правому краю, при n< 0 - по левому.

Задача: дан массив, содержащий температуру воздуха для каждого часа на каждый день месяца. Вывести эти значения в текстовый файл в виде таблицы, при этом добавить колонку средних температур.

 
program Example;

(******************************************************

* Задача: дан массив, содержащий температуру  воздуха  *

* для каждого часа  на каждый день  месяца. Вывести эти  *

* значения в текстовый  файл в виде  таблицы, при этом  *

* добавить среднюю  температуру.            

          *

******************************************************)   

const

  MONTHNAME='Июнь';

  MINTEMPER=15;

  MAXTEMPER=36;

var

  OutFile: Text; {файл таблицы}

  FileName: string;

  Temper : array [1..31,1..24] of byte; {массив температур}

  i, j, Sum: integer 

(******************************************************

Процедура заполняет массив температур случайными

значениями. Распределение, конечно, получится нереальным,

но  для иллюстрации  этого будет достаточно.

******************************************************)

procedure CountArray;

var

  i, j: integer;

begin

  for i:=1 to 31 do

    for j:=1 to 24 do

      Temper[i,j] := Random(MAXTEMPER-MINTEMPER)+MINTEMPER;

end 

begin

  {Заполняем массив температур}

  CountArray;

  write('Введите имя файла для вывода таблицы '); readln(FileName);

  Assign(OutFile, FileName);

  Rewrite(OutFile);

  {Шапка таблицы}

  writeln(OutFile,'Температура воздуха на месяц: ',MONTHNAME);

  for i:=1 to 26 do

    write(OutFile,'+---');

  writeln(OutFile,'+');

  write(OutFile,'|   |Ср.|');

  for i:=1 to 24 do

    write(OutFile,i:3,'|');

  writeln(OutFile);

  for i:=1 to 26 do

    write(OutFile,'+---');

  writeln(OutFile,'+');

  {Вывод значений температуры}

  for j:=1 to 31 do begin

    {Сумма дневных температур для вычисления средней}

    Sum:=0;

    for i:=1 to 24 do

      Sum:=Sum+Temper[j,i];

    {Выводим среднюю и почасовые температуры}

    write(OutFile,'|',j:3,'|');

    if Sum>0 then

      write(OutFile, '+',(Sum div 24):2,'|')

    else

      write(OutFile, (Sum div 24):3,'|');

    for i:=1 to 24 do

      if Temper[j,i]>0 then

        write(OutFile,'+',Temper[j,i]:2,'|')

      else

        write(OutFile,Temper[j,i]:3,'|');

    writeln(OutFile);

  end;

  {Закрываем таблицу и файл}

  for i:=1 to 26 do

    write(OutFile,'+---');

  writeln(OutFile,'+');

  Close(OutFile);

end.

В случае, когда  массив температур заполняется случайными числами, мы получим в файле результат  вроде этого (приведена левая  часть таблицы):

 
Температура воздуха на месяц: Июнь

+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+

|   |Ср.|  123456789| 10| 11| 12| 13| 14| 15| 16| 17| 18|

+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+

1|+23|+15|+15|+33|+19|+20|+29|+21|+18|+22|+23|+16|+24|+16|+32|+16|+21|+34|+22|

2|+24|+18|+21|+24|+20|+32|+20|+25|+18|+33|+21|+31|+35|+25|+33|+32|+15|+17|+18|

3|+27|+31|+29|+26|+19|+29|+27|+35|+28|+35|+20|+29|+21|+16|+31|+25|+33|+25|+27|

...

| 30|+22|+30|+34|+20|+18|+17|+35|+17|+22|+18|+23|+25|+17|+22|+21|+20|+16|+21|+32|

| 31|+23|+16|+31|+23|+15|+29|+25|+24|+30|+15|+17|+20|+26|+31|+28|+20|+32|+25|+24|

+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+

Конечно, такая  таблица никоим образом не соответствует  реальному распределению температур, но мы стремились только проиллюстрировать  табличный вывод данных.

Еще одна дополнительная особенность текстовых файлов в  Паскале - возможность их дозаписи. При этом файл открывается директивой Append вместо Rewrite. Например, после выполнения фрагмента:

 
Rewrite (F);

writeln (F, 'Куда идем мы с Пятачком -');

Close (F);

Append (F);

writeln (F, 'Большой-большой секрет.');

Close (F);

Содержимое файла F будет иметь вид:

 
Куда  идем мы с Пятачком -

Большой-большой  секрет.

Ввод-вывод  для бестиповых файлов

Буфер - это область памяти, которая выделяется для каждого файла при его открытии.

Мы уже говорили, что информация, записываемая в файл, вначале оказывается в буфере оперативной памяти, а в файл перебрасывается, только когда весь буфер заполнен. Точно так же и при чтении из файла сразу считывается столько  байт, каков размер буфера. Дальнейший запрос данных будет обращен именно к буферу.

Например, если буфер вмещает 64 байта, а программа  запрашивает из файла 4, то в буфер  считается 64 байта из файла, затем 4 первых из них будет передано программе. Остальные либо передадутся по запросу  позже, либо будут потеряны, если чтение этого участка файла прекратится.

Стандартные операторы Reset(F) и Rewrite(F) при открытии бестипового  файла устанавливают размер буфера в 128 байт. Но можно задать этот размер программно при помощи операторов Reset (var F: File; BufSize: Word) и Rewrite (var F: File; BufSize: Word). Чем больше размер буфера, тем меньше будет при выполнении программы  обращений к диску и значит, тем быстрее будет выполняться  программа, поскольку обращение  к диску производится гораздо  медленнее, чем к памяти.

Однако, если мы считываем информацию небольшими блоками  и не последовательно, а напрямую, такое увеличение буфера может даже снизить производительность.

Минимально возможный  размер считываемого или записываемого  блока - 1 байт, максимальный - 64 килобайта.

Поскольку в  бестиповых файлах речь может идти только о работе с отдельными байтами, то считывание и запись информации также производится блоками по несколько  байт.

Оператор BlockRead (var F: File; var Where; Count: Word [; var ReadIn: Word]) считывает из бестипового файла F Count емкостей буфера (размер буфера объявлен при открытии файла) и помещает всю считанную информацию в память начиная с адреса Where.

Параметр ReadIn необязателен, в него записывается целое число  блоков (буферов), которое действительно  считалось в процессе операции. ReadIn удобно использовать для отслеживания ошибок чтения.

Count*Размер_буфера  не может превышать 64 килобайта.  Это обязательное условие для  DOS-программы.

Для записи информации в бестиповой файл используется оператор BlockWrite (var F: File; var Where; Count: Word [; var WriteOut: Word]). Здесь параметр Where указывает на адрес начала буфера в оперативной памяти, откуда берется информация, а необязательный аргумент WriteOut после окончания операции будет содержать действительное количество записанных в файл блоков.

Например:

 
var

  {объявляем буфер в виде массива в памяти}

  Buf : Array [1..10] of integer;

  F : File;

  Value : integer;

...

Reset(F,16); {открываем бестиповый файл, размер буфера 16 байт}

{чтение  из файла 32 байт (2*16) и запись по  адресу 1 элемента  массива}

BlockRead (F,Buf,2);

{чтение  из файла 64 байт  и запись по  адресу 5 элемента  массива}

BlockRead (F,Buf[5],4); - чтение в Х 64 байт начиная с 5 элемента

Рассмотрим  задачу: требуется побайтово скопировать один произвольный файл в другой. Программу для решения этой задачи можно составить так:

 
program Example;

(******************************************************

* Демонстрация работы  с нетипизированными  файлами и   *

* использования параметров  командной строки.          *

* Задача: побайтово  скопировать один  файл в другой.   *

******************************************************)   

var

  SrcFile, DestFile: File; {файл-источник и файл-приемник}

  NumRead, NumWrite: Word; {количество обработанных блоков}

  Buf: array [1..1024] of Char; {буфер можно задать и так}

begin

  {проверяем количество параметров командной строки}

  if ParamCount< 3 then begin

    writeln('Ошибка: недостаточно параметров командной строки.');

    exit;

  end;

  {открываем оба файла}

  Assign(SrcFile, ParamStr(2));

  {$I-}

  Reset(SrcFile, 1); {размер буфера 1 байт}

  {$I+}

  if IOResult<>0 then begin

    writeln('Ошибка: невозможно открыть исходный файл.');

    exit;

  end;

  Assign(DestFile, Param

Str(3));

  Rewrite(DestFile, 1); {размер буфера тоже 1 байт}

  {копируем}

  Writeln('Копирую файл ',ParamStr(2),' в ', FileSize(SrcFile), ' байт...');

  repeat

    BlockRead(SrcFile, Buf, SizeOf(Buf), NumRead);

    BlockWrite(DestFile, Buf, NumRead, NumWrite);

  until (NumRead = 0) or (NumWrite <> NumRead);

  writeln('Копирование завершено.');

  Close(SrcFile);

  Close(DestFile);

end.

Информация о работе Работа с файлами данных в Pascal