Работа с текстовыми файлами: запись и чтение

Урок знакомит с записью и чтением текстовых файлов в Паскале через assign, rewrite, reset и close.

Файл — это данные, сохранённые на диске; в отличие от переменных, они не исчезают после завершения программы.

Зачем программе файлы

Все наши данные до сих пор жили в переменных — в оперативной памяти. Стоит программе завершиться, и они исчезают бесследно. Но что, если нужно сохранить результат, чтобы воспользоваться им завтра? Или, наоборот, прочитать большой набор данных, который неудобно вводить руками? Здесь на помощь приходят файлы — постоянное хранилище на диске. Программа может записать данные в файл и потом, в другой запуск, прочитать их обратно.

Аналогия: переменные — это мысли в голове, они забываются. Файл — это записная книжка: записал — и информация сохранилась надолго. Мы разберём текстовые файлы — самые простые и читаемые, их можно открыть обычным «Блокнотом».

Файловая переменная и assign

Чтобы работать с файлом, заводят особую переменную типа text (текстовый файл). Сама по себе она пуста — её нужно связать с конкретным файлом на диске процедурой assign:

var
  f: text;            // файловая переменная
begin
  assign(f, 'data.txt');   // связываем f с файлом data.txt
  ...
end.

После assign переменная f становится «пультом управления» файлом data.txt. Все дальнейшие операции (открыть, читать, писать, закрыть) делают через неё. Сам файл пока не открыт — мы лишь указали, с каким файлом будем работать.

Запись в файл: rewrite

Чтобы записать данные, файл открывают процедурой rewrite (она создаёт новый файл или очищает существующий). Затем пишут в него знакомыми write и writeln, но первым аргументом указывают файловую переменную. В конце файл обязательно закрывают процедурой close:

var
  f: text;
  i: integer;
begin
  assign(f, 'numbers.txt');
  rewrite(f);                    // открываем на запись
  writeln(f, 'Список чисел:');   // пишем в файл, а не на экран
  for i := 1 to 5 do
    writeln(f, i, ' в квадрате = ', i * i);
  close(f);                      // закрываем — данные сохранены
  writeln('Готово! Данные записаны в файл.');
end.

Обратите внимание: writeln(f, ...) с файловой переменной пишет в файл, а обычный writeln(...) — на экран. После выполнения на диске появится файл numbers.txt с шестью строками. Процедура close критически важна: пока файл не закрыт, данные могут остаться в буфере и не записаться. Забыть close — частая причина «пропавших» данных.

Чтение из файла: reset

Чтобы прочитать существующий файл, его открывают процедурой reset (открыть для чтения с начала). Дальше читают через read/readln с файловой переменной. Поскольку мы обычно не знаем заранее, сколько в файле строк, читают в цикле while с проверкой функции eof («конец файла» — end of file), которая возвращает true, когда файл закончился:

var
  f: text;
  line: string;
begin
  assign(f, 'numbers.txt');
  reset(f);                  // открываем на чтение
  while not eof(f) do        // пока не конец файла
  begin
    readln(f, line);         // читаем строку из файла
    writeln(line);           // выводим её на экран
  end;
  close(f);                  // закрываем
end.

Конструкция while not eof(f) do — стандартный способ прочитать файл целиком: «пока не достигнут конец, читай очередную строку». Это безопасно работает с файлом любого размера. Не забудьте close и здесь — закрывать нужно любой открытый файл.

Три режима открытия

ПроцедураЧто делает
rewrite(f)создать новый файл для записи (старое содержимое стирается)
reset(f)открыть существующий файл для чтения с начала
append(f)открыть для дозаписи в конец (не стирая старое)

Будьте осторожны: rewrite стирает всё, что было в файле. Если нужно добавить данные, не потеряв старые, используйте append.

Демонстрация логики на Python

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

file_lines = []                       # имитация файла в памяти
# 'запись' (аналог rewrite + writeln)
file_lines.append('Список чисел:')
for i in range(1, 6):
    file_lines.append(str(i) + ' в квадрате = ' + str(i * i))
# 'чтение' (аналог reset + while not eof + readln)
for line in file_lines:
    print(line)

Вывод:

Список чисел:
1 в квадрате = 1
2 в квадрате = 4
3 в квадрате = 9
4 в квадрате = 16
5 в квадрате = 25

В настоящем Паскале вместо списка был бы файл на диске: writeln(f, ...) для записи и readln(f, line) в цикле while not eof(f) для чтения.

Попробуй сам

Мысленно (или в PascalABC.NET на своём компьютере) напишите программу, которая записывает в файл tablica.txt таблицу умножения на 7 (строки вида «7 x 1 = 7»), затем открывает этот файл на чтение и выводит его содержимое на экран. Логику записи-чтения проверьте на Python:

file_lines = []
for i in range(1, 6):
    file_lines.append('7 x ' + str(i) + ' = ' + str(7 * i))
for line in file_lines:
    print(line)

Вывод:

7 x 1 = 7
7 x 2 = 14
7 x 3 = 21
7 x 4 = 28
7 x 5 = 35

Частые ошибки

  • Забыли close. Без закрытия записанные данные могут не сохраниться на диск, а открытый файл останется заблокированным. Закрывайте любой открытый файл.
  • rewrite вместо append. rewrite стирает существующее содержимое. Чтобы дописать, не потеряв старое, нужен append.
  • Чтение несуществующего файла. reset для файла, которого нет на диске, вызовет ошибку. Файл нужно сначала создать.
  • Забыли файловую переменную в write/read. writeln(f, x) пишет в файл, а writeln(x) — на экран. Перепутав, вы выведете данные не туда.
  • Чтение за концом файла. Без проверки eof цикл может попытаться прочитать после конца файла и упасть.

Итоги

  • Файл хранит данные на диске постоянно; для работы заводят переменную типа text и связывают её с файлом через assign.
  • rewrite открывает для записи (стирая старое), reset — для чтения, append — для дозаписи в конец.
  • Чтение и запись делают через read/readln и write/writeln, указывая файловую переменную первым аргументом.
  • Файл читают целиком в цикле while not eof(f); по окончании работы файл обязательно закрывают close.
  • Главные опасности — забытый close и случайное затирание данных через rewrite.
Проверьте себя
1. Какая процедура связывает файловую переменную с именем файла на диске?
Areset
Bassign
Crewrite
Dclose
2. Чем опасна процедура rewrite при работе с существующим файлом?
AОна открывает файл только для чтения
BОна стирает всё прежнее содержимое файла
CОна не закрывает файл
DОна удваивает данные в файле
3. Зачем нужна проверка not eof(f) в цикле чтения файла?
AЧтобы ускорить чтение
BЧтобы читать строки, пока не достигнут конец файла, и не выйти за его пределы
CЧтобы открыть файл
DЧтобы закрыть файл
Поддержать проект