Песни о Паскале
Шрифт:
Закрытие файла освобождает память, выделенную для него операционной системой, и снимает блокировку, давая возможность другим программам делать с файлом все что угодно. Закрытие освобождает и саму файловую переменную, – теперь ею можно воспользоваться для доступа к другому файлу.
На рис. 55 показаны этапы чтения данных из файла.
Рис.55 –
Последовательный доступ к файлу
Как видите, читать текстовый файл можно только последовательно, строку за строкой – от начала к концу файла, – нельзя читать строки в ином порядке. Поэтому текстовые файлы относят к файлам с последовательным доступом. В отличие от них, бинарные файлы (например, файлы баз данных) допускают произвольный доступ.
Впрочем, механизм последовательного доступа не запрещает программисту в любой момент вернуться к началу файла и повторить чтение – достаточно вызвать процедуру Reset.
Самореклама
Теперь испытаем то, что узнали о чтении текстовых файлов. Напишем небольшую программу, выводящую на экран свой собственный исходный текст, вот её первый вариант.
{ P_25_1 – распечатка текста программы }
var F: text; { файловая переменная }
S: string; { строка }
begin
Assign(F, 'P_25_1.pas'); { назначаем собственное имя }
Reset(F); { открываем файл для чтения }
repeat
if Eof(F) then Break; { прекратить, если конец файла }
Readln(F, S); { прочитать строку из файла }
Writeln(S); { вывести строку на экран }
until false;
Close(F); { закрываем файл }
Readln; { ждать Enter }
end.
Выделенный курсивом оператор проверяет достижение конца файла, и делает это перед чтением строки. Если же проверять в конце цикла
...
until Eof(F);
это неизбежно приведет к ошибке после чтения последней строки файла.
Цикл с проверкой в начале
Достижение конца файла надо проверять своевременно! Для этого в Паскале есть подходящий оператор цикла, – пора познакомиться с ним. До сих пор мы обходились двумя циклическими операторами, а именно:
• циклом с проверкой условия в конце REPEAT-UNTIL;
• циклом со счетчиком FOR-TO-DO.
Новый для нас оператор цикла строится из двух ключевых слов, вот его
WHILE <условие> DO <оператор>
По-русски это читается так: "ПОКА условие истинно, ВЫПОЛНЯТЬ оператор такой-то". После ключевого слова DO допускается лишь один оператор, но на практике требуется больше. Потому здесь часто вставляют операторный блок BEGIN-END, в итоге получается такая конструкция.
WHILE <условие> DO BEGIN
<последовательность операторов>
END
Обратите внимание, что условия продолжения циклов в операторах WHILE-DO и REPEAT-UNTIL взаимно противоположны! Первый из них выполняется, пока условие истинно, а второй – пока оно ложно.
С новым оператором «самораспечатка» станет такой.
{ P_25_2 – распечатка текста программы }
var F: text; { файловая переменная }
S: string; { строковая переменная }
begin
Assign(F, 'P_25_2.pas'); { назначаем собственное имя }
Reset(F); { открываем файл для чтения }
while not Eof(F) do begin { пока не конец файла }
Readln(F, S); { прочитать строку из файла }
Writeln(S); { вывести строку на экран }
end;
Close(F); { закрываем файл }
Readln; { ждем нажатия Enter }
end.
В условии цикла WHILE видим отрицание NOT, значит, цикл будет выполняться, пока НЕ обнаружен конец файла. Проверьте работу этой программы. В следующей главе мы рассмотрим запись данных в текстовый файл и завершим наш шифровальный проект. А сейчас, как обычно, подведем итоги.
Итоги
• Текстовые файлы содержат строки видимых символов, отделенные друг от друга невидимыми на экране управляющими кодами CR (возврат каретки) и LF (перевод строки).
• К текстовым файлам обращаются через файловые переменные типа TEXT.
• Перед чтением файла нужны два шага: 1) связывание файловой переменной с именем файла процедурой Assign, и 2) открытие файла для чтения процедурой Reset.
• Для чтения отдельных строк вызывают процедуру Readln, при этом первым параметром процедуры указывают файловую переменную.
• После открытия файла его чтение начинается с первой строки; каждый вызов процедуры Readln смещает позицию чтения в начало следующей строки.
• Чтение файла возможно, пока не будет прочитана последняя строка. Попытка чтения за концом файла вызовет аварию программы.
• Чтобы узнать о достижении конца файла, вызывают функцию Eof, которая возвращает TRUE, если достигнут конец файла.
• Признак окончания файла исследуют в начале цикла, и для этого лучше подходит оператор цикла WHILE-DO.