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

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

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

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

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

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

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

4. Прямой доступ  к файлу данных

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

Например, пусть  файл F - типизированный:

 
Reset(F); {сейчас мы можем считать 1-й компонент файла}

for i:=1 to 20 do

  Read (F, v); {в переменной v значение 20-го компонента файла}

Reset(F); {а сейчас мы снова готовы читать 1-й компонент}

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

Функция FileSize(var F) : LongInt возвращает число записей в открытом файле F. Записями будут считаться компоненты типизированного файла или блоки размером с буфер бестипового. Причем для нетипизированного файла функция возвращает число полных блоков: оставшийся неполный "хвост" не учитывается.

Функция FilePos(var F) : LongInt возвращает номер последнего считанного компонента или блока. Для начала файла функция вернет 0, для состояния конца файла - номер последнего компонента (блока).

Процедура Seek(var F; N: LongInt) устанавливает файловый курсор на компонент или блок с номером N, считая нулевым блоком начало файла. N-й компонент будет считан или записан следующей операцией ввода-вывода. Файл при этом должен быть открыт.

Для демонстрации прямого доступа давайте рассмотрим следующий пример:

 
const

  FILENAME = 'example.dat';

var

  F: File of char;

  ch: char;

  i: integer;

begin

  writeln('Работаем с файлом "example.dat"');

  Assign(F, FILENAME);

  Rewrite(F);

  writeln('Текущий размер файла = ', FileSize(F));

  writeln('Текущая позиция в файле = ', FilePos(F));

  for i:=1 to 20 do begin

    ch:=chr(ord('0')+random(10));

    Write(F,ch);

    end;

  writeln('Теперь размер файла - ', FileSize(F));

  writeln('И текущая позиция в нем - ', FilePos(F));

  Seek(F, FileSize(F) div 2);

  writeln('Теперь текущая позиция = ', FilePos(F));

  ch:='У'; Write(F,ch);

  ch:='Р'; Write(F,ch);

  ch:='А'; Write(F,ch);

end.

Вывод на экран  при выполнении этой программы будет  следующим:

 
Работаем  с файлом "example.dat"

Текущий размер файла = 0

Текущая позиция  в файле = 0

Теперь размер файла - 20

И текущая позиция  в нем - 20

Теперь текущая  позиция = 10

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

0082263134УРА8029373

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

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

Библиотеку можно  заполнять и вручную, но это долго  и неудобно. Давайте вначале создадим модуль создания файла "базы данных" библиотеки, для которого книги будут  генерироваться случайным образом  из заданных списков значений.

 
program CreateLibrary;

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

* Для задач об  имитации базы  данных "Библиотека" при  *

* помощи типизированного  файла. Создание  библиотеки   *

* из случайно генерируемых  книг.                      *

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

const

  {константы для жанров}

  KINDSNUM = 6;

  KINDMAX = 10;

  CKinds : array [1..KINDSNUM] of string[KINDMAX] =

    ('Проза','Учебная','Детская','Фантастика','Классика','Поэзия');   

  {константы для авторов}

  AUTHORSNUM = 17;

  AUTHORMAX = 15;

  CAuthors : array [1..AUTHORSNUM] of string[AUTHORMAX] =

    ('А.С.Пушкин','Н.В.Гоголь','Ф.М.Достоевский','В.Астафьев','С.Лем',

     'А.П.Чехов','Ф.Купер','А.Дюма','С.Лукьяненко','О.Дивов','В.Лукин',

     'Т.Сван','Б.Страуструп','У.Гибсон','Н.Стивенсон','Р.Рюкер','Н.Носов');   

  {константы для названий}

  NAMESNUM = 34;

  NAMEMAX = 40;

  CNames : array [1..NAMESNUM] of string[NAMEMAX] =

    ('Руслан и Людмила','Сказка о рыбаке и рыбке','Мертвые души',

     'Вечера на хуторе близ Диканьки','Преступление и наказание',

     'Братья Карамазовы','Идиот','Царь-рыба','Рассказы','Жалобная книга',

     'Лошадиная фамилия','Зверобой','Следопыт','Три мушкетера','Две Дианы',

     'Императоры иллюзий','Фальшивые зеркала','Спектр','Выбраковка',

     'К-10','Рыцари кувалды','Миссионеры','Программирование в Delphi',

     'Программирование в Borland Builder C++','Язык С++ для профессионалов',

     'Джонни-мнемоник','Нейромант','Все вечеринки завтрашнего дня',

     'Лавина','Алмазный век','Белый свет','Приключения Незнайки',

     'Веселая семейка','Мишкина каша') 

  {константы для издательств}

  PUBLICSNUM = 9;

  PUBLICMAX = 15;

  CPublics : array [1..PUBLICSNUM] of string[PUBLICMAX] =

    ('АСТ','Дрофа','Амфора','Альфа-книга','Радио и связь','Питер','Наука',

     'Эксмо','Медицина');   

type

  TBook = record

    Kind: string[KINDMAX];

    Author: string[AUTHORMAX];

    Name: string[NAMEMAX];

    Public: string[PUBLICMAX];

    Year: word;

  end 

var

  Library: File of TBook;

  FileName: string;

  book: TBook;

  num, tmp, minyear, maxyear, i: word;

  ask: char 

begin

  {вводим диапазоны}

  write('Введите количество книг в библиотеке: '); readln(num);

  write('Введите минимальный год издания: '); readln(minyear);

  write('Введите максимальный год издания: '); readln(maxyear);

  {минимум должен быть меньше максимума}

  if minyear>maxyear then begin

    tmp:=minyear;

    minyear:=maxyear;

    maxyear:=tmp;

  end;

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

  Assign(Library, FileName);

  Rewrite(Library);

  for i:=1 to num do begin

    {генерируем книгу из случайных полей}

    tmp:=random(KINDSNUM)+1;

    book.Kind := CKinds[tmp];

    tmp:=random(AUTHORSNUM)+1;

    book.Author := CAuthors[tmp];

    tmp:=random(NAMESNUM)+1;

    book.Name := CNames[tmp];

    tmp:=random(PUBLICSNUM)+1;

    book.Public := CPublics[tmp];

    book.Year := random(maxyear-minyear)+minyear;

    {записываем получившуюся книгу в файл}

    Write(Library, book);

  end;

  Close(Library);

  writeln('Библиотека создана');

  write('Хотите ли вы просмотреть получившуюся библиотеку? (д/н)'); readln(ask);

  if (ask='y')or(ask='Y')or(ask='д')or(ask='Д') then begin

    Reset(Library);

    writeln;

    writeln('КАТАЛОГ БИБЛИОТЕКИ');

    while not EOF(Library) do begin

      read(Library, book);

      writeln(book.Kind:KINDMAX,'|',book.Author:AUTHORMAX,'|',

              book.Name:NAMEMAX,'|',book.Public:PUBLICMAX,'|',

              book.Year:4);

    end

  end;

end.

Теперь сама программа подсчета:

program Library1;

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

* Задача: в файле  данных записаны сведения о  книгах:  *

* жанр, автор, название, издательство, год издания.   *

* Необходимо подсчитать  количество книг заданного     *

* автора.                                             *

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

const

  {Максимальные  размерности полей}

  KINDMAX = 10;

  AUTHORMAX = 15;

  NAMEMAX = 40;

  PUBLICMAX = 15;

type

  TBook = record

    Kind: string[KINDMAX];

    Author: string[AUTHORMAX];

    Name: string[NAMEMAX];

    Public: string[PUBLICMAX];

    Year: word;

  end; 

var

  Library: File of TBook;

  FileName: string;

  author: string[AUTHORMAX];

  book: TBook;

  num, ErrCode: word; 

begin

  {открываем библиотеку}

  repeat

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

    Assign(Library, FileName);

    {$I-}

    Reset(Library);

    {$I+}

    ErrCode:=IOResult;

    if ErrCode<>0 then

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

  until ErrCode=0;

  write('Введите  имя автора: '); readln(author);

  {подсчитываем  книги этого автора}

  num:=0;

  while not EOF(Library) do begin

    Read(Library, book);

    if book.Author=author then

      num:=num+1;

  end;

  Close(Library);

  writeln('Количество книг автора ',author,' в библиотеке = ',num,' шт.');

end.

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