Текущий указатель

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

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

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

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

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

Компилятор Турбо Паскаля поддерживает три типа файлов: текстовые, типизированные, нетипизированные.

Средства обработки файлов.

TURBO PASCAL вводит ряд процедур и функций, применимых для любых типов файлов: Assign, Reset, Rewrite, Close, Rename, Erase, Eof, IOResult.

 

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

 

Процедура Assign( var f; FileName: String ) связывает логический файл f с физическим файлом, полное имя которого задано в строке FileName.

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

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

 

Процедура Reset ( var f ) открывает логический файл f для последующего чтения данных или, как говорят, открывает входной файл. После успешного выполнения процедуры Reset файл готов к чтению из него первого элемента.

Имеются некоторые отличия в использовании процедуры Reset при открытии различных типов файлов. В отношении текстовых файлов (тип Text) действие процедуры означает открытие файла только для чтения. Дня нетипизированных файлов в описание процедуры добавляется еще один параметр RecSize типа word, который устанавливает длину записи для функций обмена с файлом.

 

Процедура Rewrite( var f ) открывает логический файл f для последующей записи данных (открывает выходной файл). После успешного выполнения этой процедуры файл готов к записи в него первого элемента.

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

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

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

 

Процедура Close( var f ) закрывает открытый до этого логический файл.

Вызов процедуры Close необходим при завершении работы с файлом. Если по какой-то причине процедура Close не будет выполнена, файл все - же будет создан на внешнем устройстве, но содержимое последнего буфера в него не будет перенесено. Для входных файлов использование оператора закрытия файла необязательно. Использование процедуры Close позволяет устранить связь файловой переменной с внешним файлом, установленную с помощью процедуры Assign.

 

Логическая функция EOF( var f ): Boolean возвращает значение TRUE, когда при чтении достигнут конец файла. Это означает, что уже прочитан последний элемент в файле или файл после открытия оказался пуст.

 

Процедура Rename( var f; NewName: String ) позволяет переименовать физический файл на диске, связанный с логическим файлом f. Переименование возможно после закрытия файла.

 

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

 

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

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

 

Рассмотренные операции ввода-вывода охватывают все типы файлов в Турбо Паскале и характеризуют взаимоотношения файловой и операционной систем.

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

Текстовый файл содержит последовательность символов, организованных в строки, причем каждая строка заканчивается специальным символом возврата каретки CR=#13 и перевода строки LF=#10. Эти два символа задают стандартные действия по управлению текстовыми файлами. Стандартно открываемые предопределении файлы Input и Output в модуле System имеют тип Text. Заканчивается файл признаком конца файла.

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

var f: Text; {F — файловая переменная}

Далее переменная f сопоставляется внешнему файлу на диске или какому-нибудь устройству процедурой Assign:

Assign(in_file, ‘primer.txt’);

Assign(in_file, ‘C:\text\primer.txt’);

Assign(in_file, ‘prn’);

 

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

 

Procedure Reset(var F) Открывает существующий файл, связанный с файловой переменной F. При отсутствии файла, выдается сообщение об ошибке. Текущий указатель устанавливается в начало файла. Текстовый файл открывается только для чтения
Procedure Rewrite(var F) Создает и открывает новый файл, связанный с файловой переменной F. Если файл с указанным именем уже существует, старый файл будет стерт, а на его месте создан новый пустой файл. Текущий указатель устанавливается в начало файла
Procedure Append(var F: text) Открывает существующий файл, связанный с файловой переменной F, для добавления в него новых записей

 

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

Для записи в текстовый файл или чтения из него можно использовать процедуры Write, WriteLn, Read, ReadLn. В этом случае в качестве первого параметра в этих процедурах указывается файловая переменная, например: Read(f, a, x).

У текстовых файлов своя специфика. Специальные расширения стандартных процедур чтения Read и записи Write разрешают работать со значениями несимвольного типа. При считывании значений или их записи в файл происходит автоматическое преобразование из числового формата в символьный и наоборот.

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

 

Procedure Read(var F:Text, v1,…) Считывает одно или несколько значений из файла, связанного с файловой переменной F, в одну или несколько переменных v1,…
Procedure ReadLn(var F:Text, v1,…) То же, что и Read, но выполняет после считывания пропуск до начала следующий строки текстового файла
ReadLn(F) пропускает строку до начала следующей;
Procedure Write(var F:Text, v1,…) Записывает в файл, связанный с файловой переменной F, одно или несколько значений, хранящихся в переменных v1,… Значения могут иметь целый, вещественный, строковый, символьный или булевский тип
Procedure WriteLn(var F:Text, v1,…) То же, что и Write, но затем записывает в текстовый файл признак конца строки
WriteLn(F) -   Завершает строку файла, в которую производится запись, признаком конца строки и переходит к началу следующей.

 

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

Function SeekEOF(var F: text): Boolean возвращает значение True, если до конца файла остались строки, заполненные пробелами.
Function SeekEOLn(var F: text): Boolean возвращает значение True, если до конца строки остались только пробелы.
Функция Eoln(var F: text) возвращает булевское значение True, если текущая файловая позиция находится на маркере конца строки

 

Типизированные файлы

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

Типизированные файлы состоят из машинных представлений значений переменных, они хранят данные в том же виде, что и память ЭВМ.

 

Описание типизированного файла имеет вид:

 

var ftable: file of type_ID;

 

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

При работе с типизированными файлами используются уже знакомые процедуры Assign, Reset и ReWrite. Однако следует заметить, что текстовый файл, открытый процедурой Reset, доступен только для чтения, а типизированный – еще и для записи. Процедуры Read и Write здесь используются по-другому. Отличие заключается в том, что каждый из параметров в рассматриваемом случае должен быть переменной типа type_ID, а выражения и константы недопустимы. Процедуры ReadLn и WriteLn к типизированным файлам не применяются.

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

 

К типизированным файлам применяются следующие процедуры и функции:

 

Function EOF(var F): Boolean Возвращает для файла, связанного с файловой переменной F, состояние End-Of-File (конец файла); True – если текущее положение указателя находится в конце файла или файл пустой; False – во всех остальных случаях
Function FilePos(var F): LongInt Возвращает текущую позицию для файла, связанного с файловой переменной F. При положении текущего указателя в начале файла возвращается нулевое значение
Function FileSize(var F): LongInt Возвращает текущий размер файла, связанного с файловой переменной F. Если файл пустой, возвращается нулевое значение
Procedure Seek (var F: N: LongInt) Перемещает текущую позицию в файле, связанным с файловой переменной F, на заданный элемент. Началу файла соответствует нулевое значение N
Процедура Truncate( var f ) Устанавливает в текущей позиции признак конца файла и удаляет (стирает) все последующие блоки.
   

Нетипизированные файлы

Для более эффективного выполнения операций ввода/вывода из внешних файлов в Паскале имеются нетипизированные файлы. При работе с ними можно использовать быстрые дисковые операции низкого уровня. Нетипизированные файлы дают возможность прямого доступа к любому файлу независимо от его типа и структуры. Описание нетипизированной файловой переменной имеет вид

var untypfile: file;

Такая файловая переменная связывается с внешним файлом обычным образом. В числе параметров процедур Reset и Rewrite для нетипизированных файлов кроме файловой переменной имеется необязательный второй параметр типа Word:

Reset(untypfile, n);

Rewrite(untypfile, n);

Дополнительный параметр n описывает размер индивидуальной записи в файле (в байтах). Если параметр n отсутствует, его значение по умолчанию принимается равным 128, однако рекомендуется явно указывать значение 1.

Для операций ввода/вывода в нетипизированных файлах используются следующие низкоуровневые операции:

Procedure BlockRead (var F: File; var Buf; Count:Word) Считывает из нетипизированного файла, связанного с файловой переменной F, одну или несколько записей (их количество задается целочисленным выражением Count) в переменную Buf
Procedure BlockWrite (var F: File; var Buf; Count:Word) Записывает в нетипизированный файл, связанный с файловой переменной F, одну или несколько записей (их количество задается целочисленным выражением Count) из переменной Buf