Вспомним, что типизированный файл - это последовательность элементов одного типа. А раз так, то при последовательном обращении к файлу текущий указатель переходит от элемента к элементу. Возникает вопрос: можно ли игнорировать последовательный доступ к файлу и сразу, например, обратиться к третьему элементу файла? Оказывается, можно.
Если есть необходимость нарушения последовательной записи или чтения из файла, текущий указатель, может быть изменен процедурой
| Seek (МуFilе, n); |
где n - требуемое положение указателя.
Внимание! Нумерация элементов типизированного файла начинается с нуля.
Поэтому, чтобы обратиться к третьму элементу, нужно записать Seek (МуFilе, 2).
Seek (МуFilе, 0) - устанавливает указатель в начальной позиции (на первый элемент).
Seek (МуFilе, FileSize(МуFilе)) - устанавливает указатель после последнего элемента, то есть на признак конца файла.
Примечание. Функция FileSize(МуFilе) возвращает количество элементов типизированного файла МуFilе.
Текущую позицию указателя дает функция
| FilePos (МуFilе); |
Рассмотрите пример.
Пример №2. Составить программу, которая переписывает существующий файл, заменяя все латинские буквы на заглавные.
| Рrogram Writing; Var FileName: string; {строка, содержащая имя файла} FVar: file of char; {переменная файлового типа} Index: integer; Letter: char; {читаемый из файла символ} Begin write('Enter filename: '); {предложение ввести имя файла} readln (FileName); {ввод имени файла} assign (FVar,FileName); {связь имени файла и переменной} {$I-} {отключен контроль ввода/вывода} reset (FVar); {открытие файла для чтения и записи} {$I+} {включен контроль ввода/вывода} if IOResult <> 0 {выход, если файл не открыт} then begin writeln ('Не открыт файл ', FileName); Halt end; while not EOF (FVar) do {цикл до конца файла} begin read (FVar, Letter); {чтение символа из файла} Letter:=Upcase(Letter); (преобразование букв) Seek(FVar,FilePos(FVar)-1); {перемещение указателя назад на 1 позицию} write(FVar,Letter); {запись преобразованной буквы} end; {конец цикла} close(FVar) {закрыть файл} End. |
Функция IOResult
Как Вы уже заметили в предыдущей программе была использована функция IOResult. Рассмотрим, какую роль выполняет эта функция.
Функция IOResult предназначена для поиска ошибок, возникающих при работе с файлами. Эта функция возвращает результат последней операции ввода/вывода, если автоматический контроль за ошибками, возникающими при выполнении операций ввода/вывода, отключен с помощью директивы компилятора {$I-}. При безошибочном выполнении операций ввода/вывода функция IOResult всегда возвращает результат равный нулю. Поэтому, как правило, ее используют в операции сравнения с нулем. При использовании функции IOResult нужно помнить о том, что она возвращает величину, которую можно интерпретировать как флаг ошибки лишь в том случае, когда эта функция вызывается следом за операцией ввода/вывода. А если Вы хотите провести анализ ошибки позже, Вам придется сохранить возвращаемое значение в некоторой промежуточной переменной.
Просмотрите еще раз фрагмент программы, в которой посредством процедуры reset производится попытка открытия файла. Если эта попытка не увенчалась успехом, то на экран будет выведено сообщение об ошибке.
| {$I-} {отключение контроля ввода/вывода} reset (F,'C:\TP7\BIN\Text.txt'); {открытие файла для чтения} if IOResult <> 0 then writeln ('Ошибка при открытии файла'); {$I+} {включение контроля ввода/вывода} |
Изменение имени файла производится процедурой
| rename(МуFilе, FileName); |
первый аргумент которой - переменная файлового типа, а второй аргумент - строкового типа - новое имя файла, которое может быть сокращенным или полным (с указанием пути). Действие этой процедуры эквивалентно действию аналогичной процедуры DOS.
Уничтожение части файла от текущего положения до конца производится процедурой
| truncate(МуFilе); |
Уничтожение всего файла производится процедурой
| erase(МуFilе); |
действие которой эквивалентно удалению файла в операционной системе DOS.
Примечание. Физические файлы на магнитных дисках и переменные файлового типа в программе на Паскале - объекты различные. Переменные файлового типа в Паскале соответствуют не только физическим файлам, но и логическим устройствам, связанным с вводом и выводом информации. Клавиатуре и экрану дисплея соответствуют файлы со стандартными именами Input и Output.
Задание на дом. Рассмотрите предложенный ниже текст программы. Сформулируйте решенную задачу. Создайте расширенный вариант подобной задачи
| Program Files; Uses Crt; Var F,Fnew: file of string; Name,NewName: string[12]; Text: string; Ch: char; Procedure ReadText; Begin repeat write('Введите имя файла>'); readln(Name); assign(F,Name); reset(F); if IOresult<>0 then begin writeln('Ошибка чтения'); close(F); end; until IOresult=0; writeln('Содержание файла ',Name,':'); while not Eof(F) do begin readln(F,Tеxt); writeln(Tеxt); end; close(F); End; Procedure EraseFile; Begin erase(F); writeln('Файл удален'); End; Procedure ReNameFile; Begin write('Введите новое имя файла:'); readln(NewName); rename(F,NewName); writeln('Файл ',Name,' переименован в файл ',NewName); End; Procedure CopyFile; Begin write('Введите имя копии файла ',Name,'>'); readln(NewName); reset(F); assign(Fnew,NewName); rewrite(Fnew); while not Eof(f) do begin readln(F,Text); writeln(Fnew,Text); end; close(F); close(F_new); writeln('Файл',Name,' скопирован в файл ',NewName); End; Begin ClrScr; readTеxt; repeat writeln('Удаление файла (D),переименование файла(R)'); writeln('Копирование файла (C), выход из программы (Е)'); write('Введите символ нужной операции - '); readln(ch); case ch of 'D','d': EraseFile; 'R','r': ReNameFile; 'C','c': CopyFile; end; until (ch='E') or (ch='e'); read; End. |