Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ОАиП Лекции ч.2 ПОИТ.pdf
Скачиваний:
43
Добавлен:
24.02.2016
Размер:
1.08 Mб
Скачать

РАЗДЕЛ 5. ФАЙЛЫ

5.1. Общие сведения

Для всех рассмотренных ранее производных типов было характерно наличие заранее заданного числа компонент.

Файловый тип – это произвольная последовательность элементов, длина которой заранее не определена, а конкретизируется в процессе выполнения программы.

Это определение логического файла, т.е. того, который используется в программе (файл с точки зрения программиста).

Физический файл (набор данных) – это поименованная область памяти на внешнем носителе, в которой хранится некоторая информация (файл с точки зрения пользователя).

Элементы файла записаны в нем последовательно (рисунок 5.1).

 

F

 

F1

F2

F3

 

 

 

 

 

 

 

 

 

файл

 

элементы файла

 

длина не

 

 

зафиксирована

 

 

 

 

 

 

Рисунок 5.1 – Структура файла

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

При последовательном доступе по файлу можно двигаться только последовательно, начиная с первого его элемента. У последовательного файла доступен лишь очередной его элемент. Чтобы добраться до n-го элемента файла, необходимо начать с первого элемента и пройти через предыдущие n – 1 элементов.

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

Файловый тип - это единственный тип значений, посредством которого данные, обрабатываемые программой, могут быть получены извне, а результаты могут быть переданы человеку. Это единственный тип значений, который связывает программу с периферийными устройствами компьютера.

79

В Паскале имеется три типа файлов (три вида переменных файлового типа, т.е. файловых переменных):

текстовые файлы;

файлы с типом;

файлы без типа.

Синтаксис задания файлового типа имеет вид, который представляет рисунок 5.2.

<Файловый_тип>::=

File

Of

<Тип>

Text

Рисунок 5.2 – Синтаксическая диаграмма задания фалового типа

Над значениями файлового типа не определены никакие операции (даже присваивание файловой переменной значения другой файловой переменной).

Все операции могут производиться лишь с элементами файлов. Множество операций над элементами файла определяется типом элементов.

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

Для удобства описания действия этих процедур используется понятие «окно файла» («окно», текущая позиция файла, указатель файла). Окно определяет позицию доступа, т.е. тот элемент файла, который доступен для чтения или для записи.

Позиция файла, следующая за последним элементом файла (или первая позиция пустого файла) помечается специальным маркером конца файла (Ctrl - Z при создании текстового файла с клавиатуры). С помощью этого маркера определяется конец файла.

80

5.2. Процедура Assign

Любым другим процедурам ввода-вывода предшествует процедура

Assign.

Формат ее заголовка:

Assign (Var F; Name: String)

Здесь F – имя файловой переменной любого типа; Name – выражение строкового типа.

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

Имя конкретного набора данных определяется переменной Name. Name – это полное имя физического файла. В общем случае оно имеет вид:

<Диск>:\<Имя_каталога>\\<Имя_каталога>\<Имя_файла>

<Диск> задается символом от A до Z (символ логического устройства). Если он опущен, то подразумевается логическое устройство, принятое по умолчанию.

\<Имя_каталога>\\<Имя_каталога>\ - это путь через подкаталоги к фактическому имени файла. Если они опущены, то считается, что файл находится в текущем каталоге.

<Имя_файла> - фактическое имя файла. Оно может иметь максимально 8 символов. Затем может идти уточнение (тип файла) – максимально 3 символа, отделенное от имени точкой.

Например, можно определить такие имена файлов:

Rez

Rez.pas

Rez.exe

Rez.txt

Rez.dat

Уточнение помогает программисту, пользователю, системе программирования или операционной системе работать с файлами.

Пример полного имени файла:

A:\Katalog1\Katalog2\Rez.pas

Максимальная длина полного имени файла – 79 символов.

Чтобы связать файловую переменную (логический файл) F с физическим файлом Rez.dat нужно записать процедуру Assign со следующими параметрами:

Assign (F, ‘Rez.dat’);

81

или организовать связь в диалоге:

Var

St: String;

...

Begin

...

Writeln (‘Введите имя файла’); Readln (St);

Assign (F, St);

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

Для использования доступны следующие символические имена устройств.

1) Con

Con – устройство консоли (при вводе – это клавиатура, при выводе – экран дисплея).

Например, процедура

Assign (F, ‘Con’);

означает ввод в переменную F с клавиатуры или вывод из F на экран.

По умолчанию стандартные текстовые файлы Input и Output связаны с консолью, что соответствует следующему фрагменту программы:

Assign (Input, ‘Con’);

Assign (Output, ‘Con’);

2) Lpt1, Lpt2, Lpt3

Lpt1, Lpt2, Lpt3 – устройства печати. Если подключено одно устройство печати, то используется либо имя Lpt1 либо Prn:

Assign (F, ‘Prn’);

Assign (Output, ‘Prn’);

С данными логическими устройствами может использоваться только имя

выходного файла.

82

3) Com1, Com2

Com1, Com2 – устойства последовательного ввода-вывода, используемые для обмена данными между компьютерами. Вместо Com1 может быть использовано имя ‘Aux’.

4) Nul

Nul – нулевое устройство. Для него при выводе не осуществляется никаких действий. При попытке чтения возникает ситуация конца файла.

5) Crt

Crt – устройство текстового ввода-вывода. Аналогично устройству Con, но имеет ряд дополнительных функций управления экраном (например, установка цветов, указание места на экране для вывода и т.п.). Crt не поддерживается операционной системой.

6) ‘’

‘’ – использование пустой строки вместо имени Name. В этом случае файловая переменная F связывается с Con (по аналогии с пунктом а)). Например,

Assign (F, ‘’);

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

5.3. Файлы с типом

Состоят из однотипных компонент, тип которых указан при обьявлении.

Пример 5.1.

Примеры объявления файлов с типом.

Type

Zap = Record

I: Integer;

R: Real

End;

Var

83

F1: File Of Real;

F2: File Of Char;

F3: File Of String[50];

F4: File Of Zap;

F5: File Of Integer;

Здесь F1 - F5 – это файловые переменные.

Для работы с типизованными файлами существуют следующие

процедуры и функции ввода-вывода:

1) Процедура Assign

Процедура Assign – связывает файловую переменную с внешним файлом на диске. Описана в п.5.2.

2) Процедура Rewrite (F)

Процедура Rewrite (F) – создает и открывает новый файл F.

Окно (позиция доступа) устанавливается на первую позицию файла. Если файл был ранее открыт, то он предварительно закрывается, а затем

повторно открывается.

Если ранее в файл были записаны какие-либо элементы, они становятся недоступными.

Результат выполнения процедуры Rewrite(F) изображает рисунок 5.3.

F

Окно

Рисунок 5.3 – Результат выполнения процедуры Rewrite(F)

Перед использованием процедуры Rewrite файл F должен быть связан с внешним файлом (набором данных) процедурой Assign.

Таким образом, процедура Rewrite создает новый внешний файл с именем, присвоенным переменной F процедурой Assign.

84

3) Процедура Write (F, V1 [, V2, … , VN])

Процедура Write (F, V1 [, V2, … , VN]) – записывает в ту позицию файла, на которую указывает окно, очередной элемент файла, равный значению переменной Vi. После записи переменной Vi окно сдвигается на следующую позицию файла. Если окно достигает конца файла, файл расширяется.

Результат выполнения процедуры Write (F, V1, V2) изображает рисунок

5.4.

F

 

 

 

 

 

После записи первого

F1

 

 

 

 

 

 

 

 

элемента

 

 

 

 

 

 

 

 

Окно

F

F1 F2

После записи второго элемента

 

Окно

Рисунок 5.4 – Результат выполнения процедуры Write (F, V1, V2)

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

Пример 5.2.

Пример создания файла.

Var

 

F1: File Of Char;

 

X: Char;

 

Begin

 

Assign (F1, ‘Newfile’);

 

Rewrite (F1);

 

For I:=1 To 100 Do

 

Begin

 

<Операторы программы>

 

Write (F1, X)

{X – переменная, получаемая при

85

выполнении программы}

End;

. . .

4) Процедура Reset (F)

Процедура Reset (F) – открывает существующий файлF.

Фактически при этом открывается внешний файл с именем, присвоенным переменной F процедурой Assign. Если файл с данным именем не существует, возникает сообщение об ошибке.

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

Процедура Reset(F) может быть применена к файлу любое количество раз. При выполнении этой процедуры содержимое файла не изменяется.

Результат выполнения процедуры Reset(F) изображает рисунок 5.5.

FF1 F2 F3

Окно

Рисунок 5.5 – Результат выполнения процедуры Reset(F)

5) Процедура Read (F, V [, V2, …, VN])

Процедура Read (F, V [, V2, …, VN]) – обеспечивает чтение текущего элемента файла F (того элемента, на который указывает окно) в переменную Vi и передвигает окно на следующую позицию файла.

Чтение из файла с помощью процедуры Read можно производить только для предварительно открытого файла.

Файлы с типом всегда допускают как чтение, так и запись,

независимо от того, были они открыты с помощью процедуры Reset или

Rewrite.

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

86

перебирая компоненты с помощью процедуры Read, дойти до нужной компоненты.

Результат выполнения процедуры Read (F,V1,V2) изображает рисунок 5.6.

F

F1

 

F2

F3

 

 

 

 

Окно

 

После чтения первого

 

 

 

 

элемента

V1

 

 

 

F1

 

 

 

 

 

 

 

 

 

 

 

F F1 F2 F3

 

Окно

После чтения второго

элемента

V2 F2

Рисунок 5.6 - Результат выполнения процедуры Read (F, V1, V2)

6) Функция Eof(F)

Функция Eof(F) (End Of File) – служит для определения факта выхода при чтении за пределы файла.

Функция Eof возвращает значение признака конца файла. Если достигнут конец файла F (окно указывает на маркер конца файла – позицию, следующую за последней компонентой файла), или если файл пустой, то значение функции Eof равно True. В противном случае функция Eof возвращает значение False.

Если значение функции Eof равно True, то использование процедуры Read недопустимо.

Если в заголовке функции Eof опущено имя файла, то предполагается файл Input. Например,

L := Eof;

Здесь L – переменная типа Boolean.

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

87

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

Пример 5.3.

Чтение из файла. Пусть имеется набор данных Old.

Var

F2: File Of Char; X: Char;

Begin

Assign (F2, ‘Old’); Reset (F2);

While Not Eof (F2) Do Begin

Read (F2, X);

<Операторы обработки переменной Х> End

. . .

7) Процедура Seek (F, N)

Процедура Seek (F, N) – осуществляет прямой доступ к элементам файла

F.

Здесь N – номер элемента файла. Элементы файла нумеруются последовательно, начиная с нуля.

N может быть положительным целым выражением типа Longint. Процедура Seek позиционирует файл на указанный номер элемента, то

есть устанавливает окно файла на указанный элемент. Файл должен быть предварительно открыт.

Процедура Seek не производит операций ввода-вывода. Следующий за Seek вызов процедуры Read или Write оперирует со следующими по порядку элементами файла.

Текстовые файлы процедурой Seek не обрабатываются.

Пример 5.4.

Запись в файл F2 элементов файла F1, начиная с номера 100 (фактически это 101-ый элемент файла F1).

88

Var

C: Char;

F1, F2: File Of Char; Begin

Assign (F1, ‘Old’); Assign (F2, ‘New’);

Reset (F1);

Rewrite (F2); Seek (F1, 100);

While Not Eof (F1) Do Begin

Read (F1, C);

Write (F2, C); End;

8) Функция Filepos (F)

Функция Filepos (F) – возвращает номер текущей позиции (окна) файла F. Если окно установлено на начало файла, то функция возвращает значение 0. Если окно установлено на конец файла (Eof(F) = True) , то функция возвращает значение, равное размеру файла (то есть результату функции Filesize (F)).

Тип результата функции Filepos – Longint.

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

9) Функция Filesize(F)

Функция Filesize(F) – возвращает текущий размер файла (число элементов в файле). Тип результата – Longint. Для пустого файла возвращается значение 0.

Файл должен быть предварительно открыт.

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

Пример 5.5.

Расширение файла F (добавление элементов в конец файла).

. . .

Seek (F, Filesize (F)); Write (F, C);

. . .

89

В данном примере процедура Seek помещает окно файла за последним элементом файла (функция Filesize возвращает количество элементов, но так как они нумеруются с нуля, то значение функции Filesize совпадает с номером следующей компоненты после последней).

10) Процедура Close (F)

Процедура Close (F) – предназначена для закрытия открытого файла F. Для внешнего файла, связанного с файловой переменной F, полностью

выполняется его обновление (остатки данных из буфера ввода-вывода заносятся в файл). Затем файл закрывается и может быть повторно использован.

Пример 5.6.

Определение размера файла. Закрытие файла.

Assign (F, ‘Old’); Reset (F);

Write (‘Размер файла Old ’, Filesize (F)); {Вывод на экран размера файла} Close (F);

5.4. Текстовые файлы

Текстовый файл представляет собой последовательность символов. Однако он не эквивалентен файлу типа

T = File Of Char.

Файл типа T – это единая последовательность символов.

Особенность текстовых файлов – то, что содержащиеся в них символы разбиваются на строки. Строки могут быть различной длины (и пустые). В конце каждой строки помещается специальный управляющий символ – маркер конца строки. Обычно это два управляющих символа: возрат каретки (#13 или ^M – международное обозначение CR) и перевод строки (#10 или ^J – международное обозначение LF).

С наличием этого маркера связана логическая функция Eoln (End Of Line).

90

Функция Eoln(F) принимает значение True, если окно (текущая позиция доступа) установлено на маркер конца строки, и False – в противном случае.

Текстовые файлы – это переменные типа Text.

Тип Text относится к предопределенным структурным типам. Переменные типа Text описываются c помощью указания имени типа:

Var

X, Y: Text;

Стандартные файлы Input и Output являются текстовыми файлами. Эти файлы в программе не описываются. В начале выполнения любой программы (если не ниспользуется модуль Crt) автоматически выполняются процедуры:

Assign (Input, ’’);

Assign (Output, ’’);

Reset (Input, ’’);

Rewrite (Output, ’’);

Для работы с текстовыми файлами определены следующие процедуры и функции ввода-вывода.

1) Процедура Assign (F, Name)

Процедура Assign (F, Name) – связывает файловую переменную с внешним файлом на диске. Описана в подразд. 5.2.

2) Процедура AssignСrt(F)

Процедура AssignСrt(F) – связывает текстовые файлы с Crt (с дисплеем). Процедура аналогична процедуре Assign. Однако второй параметр Name в

ней не используется.

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

Пример 5.7.

Вывод текстового файла F на принтер или экран.

Uses Crt;

 

Var

 

F: Text;

 

K: (P, C);

{К –признак вывода, P – принтер, С – Crt}

91

Begin

If K = P Then Assign (F, ’Prn’)

Else Assigncrt (F);

3) Процедура Append (F)

Процедура Append (F) – открывает существующий текстовый файл для добавления. Предварительно файл F должен быть связан с внешним файлом процедурой Assign.

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

Если файл F уже был открыт, необходимо его предварительно закрыть. В результате выполнения процедуры Append текущая позиция (окно)

файла устанавливается в конец файла, на место маркера конца файла (#26 – код

ASCII 26 или Ctrl-Z).

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

Процедура Append определена только для текстовых файлов.

4) Процедура Rewrite (F)

Процедура Rewrite (F) – открытие нового файла F. Данная процедура описана выше для файлов с типом (см.подразд. 5.3).

Отличие для текстовых файлов: файл F открывается только для записи

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

После вызова процедуры Rewrite(F) значение функции Eof(F) всегда равно True.

5) Процедура Reset (F)

Процедура Reset (F) – открытие существующего файла F. Данная процедура описана выше для файлов с типом (см.подразд. 5.3).

Отличие для текстовых файлов: файл открывается только для чтения

(из него можно только читать, писать в него нельзя).

92

6) Процедура Read ([F,] V1 [, V2, …, VN])

Процедура Read ([F, ] V1 [, V2, …, VN]) – считывает одно или несколько значений из текстового файла F в одну или несколько переменных Vi. Данная процедура описана выше для файлов с типом (см. подразд. 5.3).

Отличия при работе с текстовыми файлами:

файл должен быть открыт для чтения (процедурой Reset);

первый параметр может быть опущен (например, Read(X, Y)), в этом случае подразумевается стандартный входной текстовый файл Input;

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

Если переменная V имеет тип Char, то из файла F в V считывается очередной символ, включая символы-разделители «Конец файла»

(значение Chr(26) – #26), и «Конец строки» (Chr(13) – #13, Chr(10) – #10). Следующая процедура Read начинается со следующего символа в файле.

Если переменная V имеет арифметический тип, то пропускаются пробелы, символы табуляции, маркеры конца строки до появления цифровой комбинации. Считывание прекращается при достижении пробела, символа табуляции, маркера конца строки или маркера конца файла. Следующее чтение начинается с вышеперечисленных символов. Если в цифровой комбинации встретились запрещенные символы (например, буква вместо цифры), то возникает сообщение об ошибке ввода-вывода.

Если переменная V имеет тип String, то в нее передается столько символов, какова длина переменной V при объявлении (если длина V меньше длины текущей строки файла) или строка файла до маркера конца строки или маркера конца файла (если длина V больше длины строки файла). Маркер в строку не заносится. В первом случае по следующей операции чтения в переменную V будет передана очередная последовательность символов из первой строки файла в соответствии с длиной переменной V. Во втором случае следующая операция считывания начинается маркером конца строки, завершающим предыдущую строку. Но процедура Read не осуществляет переход на следующую строку файла после чтения. Таким образом, нельзя использовать последовательные вызовы процедуры Read для чтения последовательных строк, так как никогда не осуществится переход из первой строки во вторую. Первый вызов процедуры Read считает первый элемент, последующие вызовы будут возвращать строку нулевой длины.

93

Поэтому при чтении из текстового файла в переменные типа String необходимо использовать не процедуру Read, а процедуру Readln.

7) Процедура Readln [([F] [,] [V1, V2, …, VN])]

Процедура Readln [([F, ] [V1, V2, …, VN])] – выполняет процедуру Read, а

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

Если при вызове процедуры отсутствует список переменных V (Readln(F)), то происходит переход к следующей строке (если она существует) или к концу файла F.

Если имя файла в процедуре Readln опущено, то подразумевается стандартный входной текстовый файл Input.

Например,

Readln (X, Y, Z);

Readln;

Процедура Readln (F, V) определена только для текстовых файлов.

8) Процедура Write ([F,] E1 [, E2, …, EN])

Процедура Write([F,] E1 [, E2, … , EN]) – записывает одно или несколько значений Ei в файл F. В общем случае E может быть выражением.

Процедура описана для файлов с типом (см. подразд. 5.3).

Отличия для текстовых файлов:

Файл должен быть открыт процедурой Rewrite или Append.

Если первый параметр (F) опущен, то подразумевается стандартный выходной текстовый файл Output. Например, Write(A, B).

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

Для данных типа Char и String выводится непосредственно их значение.

Если Ei представляет собой арифметическое значение, то перед выводом в текстовый файл оно предварительно преобразуется из внутреннего значения в десятичную систему счисления, а затем представляется в коде ASCII (по байту на десятичную цифру).

Если Ei имеет тип Boolean, то выводится строка True или False.

Если не указан формат вывода, то под вывод всех типов Ei отводится столько символов, сколько минимально необходимо. Для вывода вещественных

94

типов отводится 24 позиции, причем вещественное число будет выведено в виде мантиссы и порядка.

Значения Ei могут сопровождаться указанием формата вывода:

E:L1[: L2] .

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

9) Процедура Writeln([F,][E1,E2, …,EN])

Процедура Writeln([F,][E1,E2, …,EN]) – выполняет процедуру Write, и

затем записывает маркер конца строки в файл F.

Если отсутствует список выражений Ei, то записывается только маркер конца строки.

Если опущено имя файла, то подразумевается файл Output. Например,

Writeln(F);

Writeln(A, B, C);

Writeln;

Процедура определена только для текстовых файлов.

10) Процедура Close(F)

Процедура Close(F) – закрывает открытый файл F. Рассмотрена ранее при рассмотрении файлов с типом (см. подразд. 5.3). Особенностей для текстовых файлов нет.

Пример 5.8.

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

Var

F: Text;

Begin

 

Assign (F, ’Data.txt’);

 

Rewrite (F);

{Открытие файла F только для записи}

Write (F, A);

{Запись в файл F значения некоторой переменной А,

 

полученной в ходе вычислений}

 

95

Reset (F);

{Открытие файла F только для чтения. Перед этим

 

файл не обязательно должен быть закрыт. Это

выполняется автоматически процедурой Reset}

 

Read (F, B);

{Чтение из файла F очередного значения в некоторую

переменную В}

 

Close (F);

{Обязательное явное закрытие файла F перед

 

использованием процедуры Append. Связь с внешним

 

файлом при этом сохраняется. Поэтому повторное

использование процедуры Assign не нужно}

 

Append (F);

{Открытие файла F для дополнения}

 

Write (F, C);

{Запись в конец файла F значения некоторой

переменной С, полученной в ходе вычислений}

 

Close (F);

{Закрытие файла F в конце работы с ним}

 

End.

 

 

 

11) Процедура SetTextBuf (F, Buf [, Size])

Процедура SetTextBuf (F, Buf [, Size]) – определяет буфер для текстового файла.

Процедуру следует вызывать после процедуры Assign, но до других процедур ввода-вывода. Здесь F – имя текстового файла, Buf – любая переменная (в качестве формального параметра используется параметрпеременная без типа), Size – необязательное выражение типа Word.

Обмен информацией между программой и внешним набором данных осущетвляется через буфер ввода-вывода. Это участок оперативной памяти. Размер стандартного буфера ввода-вывода, принятый по умолчанию, – 128 байт. Каждому открытому файлу назначается свой буфер.

Процедуры Write и Writeln записывают очередные элементы файла последовательно в буфер. После того, как буфер будет полностью заполнен, произойдет физическая запись содержимого буфера во внешний файл. После этого буфер освобождается для приема следующей порции информации.

Аналогично при чтении. Из внешнего файла одновременно считывается количество элементов, помещающееся в буфер. Процедуры Read и Readln читают элементы последовательно из буфера.

96

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

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

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

Процедура SetTextBuf назначает текстовому файлу F свой буфер вводавывода, определяемый параметром Buf. Размер буфера в байтах определяется параметром Size.

Если параметр Size опущен, то по умолчанию размер буфера принимается равным Sizeof (Buf), то есть вся область памяти, занимаемая параметром Buf, используется как буфер. Если параметр Size не опущен, он не должен превышать размеры переменной Buf.

Процедуру SetTextBuf нельзя применять к открытому файлу (она должна применяться после процедуры Assign и до процедур Reset, Rewrite или Append).

Процедура SetTextBuf определена только для текстовых файлов.

Пример 5.9.

Назначение буфера ввода-вывода текстовому файлу F. Передача данных из файла F в стандартный текстовый файл Output

Var

 

F: Text;

 

C: Char;

 

Buf: Array [1..10240] Of Char;

{Буфер размером 10 килобайт}

Begin

 

Assign (F, ’A:\MET\Metod.txt’);

 

SetTextBuf (F, Buf);

{Назначение буфера ввода-вывода Buf

 

текстовому файлу F. Размер буфера равен

Reset (F);

размеру переменной Buf – 10240 байт }

 

While Not Eof (F) Do

{Цикл чтения из файла F и записи в файл

Begin

Output}

 

Read (F, C);

 

Writeln (C);

 

End;

 

 

97

12) Процедура Flush (F)

Процедура Flush (F) – очищает буфер текстового файла, открытого для вывода процедурой Rewrite или Append. По данной процедуре информация из буфера, независимо от степени его заполнения (заполнен он полностью или частично), записывается во внешний файл.

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

13) Функция Eof (F)

Функция Eof (F) – конец файла.

Рассмотрена ранее при рассмотрении файлов с типом (см.подразд. 5.3).

14) Функция Eoln (F)

Функция Eoln (F) – конец строки. Рассмотрена в начале данного подраздела.

15) Функция Seekeof (F)

Функция Seekeof (F) – устанавливает файл F в состояние “конец файла”. Аналогична функции Eof, но пропускает все пробелы, метки табуляции и

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

Определена только для текстовых файлов. Файл должен быть открыт.

16) Функция Seekeoln (F)

Функция Seekeoln (F) – устанавливает файл F в состояние “конец строки”. Аналогична функции Eoln, но пропускает все пробелы и метки табуляции. Используется при считывании существующего текстового файла

числовых данных.

Определена только для текстовых файлов. Файл должен быть открыт.

98

5.5.Сравнительная характеристика представления информации в файлах с типом и текстовых файлах

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

Рассмотрим внутреннюю структуру представления информации в этих файлах.

I. Представление числовой информации.

а) В текстовом файле.

Пусть в текстовом файле записана последовательность чисел

8192, 2048,

Внутреннее представление данной последовательности в текстовом файле представляет рисунок 5.7.

Как видно из данного рисунка, числа представлены в коде обмена информацией ASCII (в распакованном формате в коде 8421). Под каждую цифру десятичного кода числа отводится один байт. Числа отделяются друг от друга хотя бы одним пробелом.

Таким образом, для хранения последовательности из двух первых чисел 8192, 2048 необходимо не менее 10 байтов.

б) В типизованном файле.

Та же последовательность чисел

8192, 2048,

в файле типа File Of Integer имеет внутреннее представление, которое иллюстрирует рисунок 5.8.

Как видно из данного рисунка, в файле типа File Of Integer числа представлены в двоичном коде в формате Integer. Под каждое число отводится два байта. Разделители между числами отсутствуют.

Таким образом, для хранения последовательности из двух первых чисел 8192, 2048 необходимо 4 байта.

99

0011

1000

0011

0001

0011

1001

0011

0010

0010

0000

 

Зона (старшая

Цифра (младшая

 

 

 

 

 

 

тетрада

тетрада байта) в Байт

 

 

 

 

 

байта)

 

коде 8421

 

 

 

 

 

 

 

 

 

 

8192 = 213

 

 

 

Пробел

 

0011

0010

0011

0000

0011

0100

0011

1000

0010 0000

 

 

 

2048 = 211

 

 

 

Пробел

 

 

 

 

 

 

 

 

 

Следующие

 

 

 

 

 

 

 

 

 

числа

Рисунок 5.7 – Представление числовой информации в текстовом файле

 

Код пробела

Код пустого Код управляющего

Код пустого

#32

символа #0

символа #8◘

символа #0

0010

0000

0000

0000

0000

1000

0000

0000

 

8192 = 213

 

 

2048 = 211

 

Рисунок 5.8 – Представление числовой информации

 

 

в файле типа File Of Integer

 

 

100

При попытке вывода данных байтов файла на экран выведется пробел (не изображается), пустой символ (не изображается), символ кода ASCII с номером

8 (изображается в виде ), пустой символ.

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

1)работа с ними осуществляется быстрее за счет следующих факторов: а) отсутствует преобразование информации, она в файле представлена так же, как в памяти; б) при работе с файлами с типом возможен режим прямого доступа;

в) меньше операций физического ввода-вывода за счет меньшего размера файла;

2)они занимают меньше места (в текстовом файле каждая цифра числа занимает байт, разделители – не менее одного пробела между числами, маркер конца строки – два управляющих символа #13#10; в файле типа File Of Integer все число занимает два байта, разделители между числами не нужны).

II.Представление текстовой информации.

а) В текстовом файле.

Пусть в текстовом файле записан текст «ВАШ ОТВЕТ НЕВЕРЕН». Пусть данный текст разбит на строки, которые изображает рисунок 5.9.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

В

А

Ш

 

#13

#10

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Конец строки

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

О

Т

В

 

Е

Т

 

#13

#10

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Н

Е

В

 

Е

Р

 

Е

Н

#13

#10

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Рисунок 5.9 – Представление текстовой информации в текстовом файле

101

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

Таким образом, для представления данной информации в текстовом файле необходим 21 байт.

б) В файле of string [7].

Тот же текст в файле типа File Of String[7] имеет внутреннее представление, которое представляет рисунок 5.10.

#3 В А Ш #0 #0 #0 #0

#5

О

Т

В

Е

Т

#0

#0

 

 

 

 

 

 

 

 

#7 Н Е В Е Р Е Н

0-ой байт – длина

Остальные байты

строки в формате Byte

– в формате Char

(значения 0-255 в

(в коде ASCII)

двоичном коде)

 

Рисунок 5.10 – Представление текстовой информации

вфайле типа File Of String [7]

Вфайле с типом строки имеют постоянную (максимальную) длину. Пустой символ (символ #0 в кодовой таблице) дополняет строки текущей длины до максимальной длины.

Следовательно, для представления данной информации в файле типа File Of String [7] необходимо 24 байта.

Сравнение файлов типа Text и File Of String показывает, что:

а) меньше места в общем случае занимает текстовый файл (так как в нем используются строки текущей длины);

б) большую скорость работы обеспечивает File Of String, так как для типизованных файлов имеется возможность работы в режиме прямого доступа,

102

работы одновременно в режиме записи-чтения, не нужно отслеживать управляющие символы #13#10 (маркер конца строки).

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

5.6. Файлы без типа

Файл без типа состоит из компонент одинакового размера. Структура этих компонент неизвестна или не имеет значения.

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

Объявление файла без типа:

Var

F: File;

Назначение файлов без типа – максимально повысить скорость обмена информацией с внешними наборами данных. Скорость обмена повышается за счет следующих факторов:

1)В файлах без типа отсутствует преобразование типа компонент;

2)Не выполняется поиск управляющих символов (типа конец строки);

3)В файлах без типа, как и в файлах с типом, возможна организация метода прямого доступа. Поэтому в них возможно одновременное использование операций чтения и записи независимо от того, какой процедурой (Reset или Rewrite) они были открыты.

4)Обмен информацией с внешними наборами данных может быть осуществлен большими блоками.

Последний фактор является основным с точки зрения повышения скорости обмена.

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

процедуры Assign, Rewrite, Reset, Seek, Close, функции Eof, Filesize, Filepos.

1) Процедуры Reset и Rewrite

Процедуры Reset и Rewrite имеют следующие особенности.

При вызове процедур Reset и Rewrite может быть использовано два параметра. Формат вызова данных процедур имеет вид:

103

Rewrite (F [,Recsize]);

Reset (F [,Recsize]);

Recsize – это необязательное выражение типа Word, определяющее размер записи (в байтах), используемый при передаче данных.

Например,

Rewrite (F, 1);

Reset (F, 1);

В данном случае второй параметр определяет длину записи в 1 байт. Если параметр Recsize опущен, то подразумевается длина записи, равная

128 байт. Это физически минимально возможный объем информации для обмена.

2) Процедура Blockread

Вместо процедур Read и Write в файлах без типа используются процедуры Blockread и Blockwrite.

Процедура Blockread имеет следующий формат вызова:

Blockread (F, Buf, Count [, Result]);

Здесь F – имя файловой переменной без типа, Buf – любая переменная (в качестве формального параметра используется параметр-переменная без типа), Count – выражение типа Word, определяющее количество считываемых записей.

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

Если Result меньше Count, то это значит, что конец файла достигнут до полного окончания передачи. В этом случае, если параметр Result отсутствует, возникает сообщение об ошибке ввода-вывода (поэтому лучше параметр Result использовать).

В результате выполнения процедуры Blockread “окно” файла (текущая позиция файла) передвинется на число записей, равное значению Result.

Объем блока информации, считываемый процедурой Blockread в переменную Buf, занимает

Result* Recsize

байтов. Здесь Recsize – размер записи, определенный при открытии файла. Размер блока информации не должен превышать 64К байта (это размер

104

сегмента данных). В противном случае возникнет сообщение об ошибке вводавывода.

3) Процедура Blockwrite

Процедура Blockwrite имеет следующий формат вызова:

Blockwrite (F, Buf, Count [, Result])

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

занимаемой переменной Buf (начиная с ее первого байта), в файл F.

Параметр Result возвращает количество полных записанных записей. Если Result меньше Count, то это значит, что диск переполнился до завершения пересылки данных. В этом случае, если параметр Result отсутствует, возникает сообщение об ошибке ввода-вывода.

В остальном описание процедуры Blockwrite аналогично процедуре

Blockread.

Пример 5.10.

Программа быстрого копирования файла F1 в файл F2.

Program CopyFile;

 

Var

 

F1, F2: File;

 

Buf: Array [1..2048] Of Char;

 

Numr, Numw: Word;

 

Begin

 

Assign (F1, ‘DATA1’);

 

Assign (F2, ‘DATA2’);

 

Reset (F1, 1);

{Размер записи при передаче

Rewrite (F2, 1);

данных равен одному байту}

Repeat

 

Blockread (F1, Buf, Sizeof (Buf), Numr);

 

Blockwrite (F2, Buf, Numr, Numw);

 

Until (Numr=0) Or (Numr<>Numw);

{Закончился файл F1

 

или переполнился диск

Close (F1);

при создании файла F2}

 

Close (F2);

 

End.

 

 

 

 

105

5.7. Проверка операций ввода-вывода

По умолчанию при выполнении операций ввода-вывода осуществляется их стандартная проверка системными средствами. Для управления проверкой служит опция компилятора {$I} – проверка ввода-вывода, которая по умолчанию включена ({$I+}). При этом, если произошла ошибка ввода-вывода, то выполнение программы прерывается и выдается сообщение о типе ошибки.

Если нежелательно, чтобы выполнение программы прерывалось по ошибке ввода-вывода, то есть если мы сами хотим обрабатывать данные ошибки, необхотимо отключить стандартную проверку ввода-вывода. С этой целью в тексте программы перед теми операциями ввода-вывода, которые программист желает контролировать сам, необходимо отключить стандартную проверку ввода-вывода опцией {$I-}, а после этих операций снова включить ее опцией {$I+}.

Для контроля операций ввода-вывода в состоянии {$I-} служит специальная функция IOResult (без параметров).

Функция IOResult возвращает целочисленное значение типа Word, которое является состоянием последней выполненной операции ввода-вывода. Если ошибки ввода-вывода не было, то функция возвращает значение ноль, в противном случае – код ошибки.

Если опция {$I} находится в состоянии {$I-} и при некоторой операции ввода-вывода произошла ошибка, то последующие операции ввода-вывода, используемые до вызова функции IOResult, будут игнорироваться.

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

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

Пример 5.11.

Использование функции IOResult для проверки наличия внешнего файла.

Var

F: File Of Char;

Begin

Assign (F, ’PRIMER’);

{$I-}

Reset(F);

{$I+}

If IOResult = 0 Then

106

Writeln (‘Размер файла:’, Filesize (F), ‘байт’) Else

Writeln (‘Файл не обнаружен’);

End.

107