Обработка файлов
| English | Русский |
|---|---|
| overwrite/ˌəʊvəˈraɪt/ | перезапись |
| APPEND/əˈpend/ | APPEND |
| temporary file/ˈtemprəri faɪl/ | временный файл |
Вы не можете изменить одну строку текстового файла
- Программа должна исправить орфографическую ошибку в середине файла клиента. Это кажется очевидным: найти строку, изменить её, сохранить.
- Почти ни один язык не позволит вам это сделать. Текстовый файл — это поток символов, а исправленное имя имеет другую длину, чем старое, поэтому каждый байт после него пришлось бы перемещать.
- Поэтому стандартный ответ заключается в том, чтобы вообще не редактировать: скопировать весь файл, изменяя эту одну строку по мере прохождения, и поместить копию на место оригинала.
- Этот урок посвящен операциям с файлами, паттерну копирования для обновления и ловушкам, которые вызывают реальные ошибки.
Операции
OPENFILE name FOR READ | WRITE | APPENDоткрывает файл. READ открывает существующий файл с начала; WRITE создает его или перезаписывает существующий; APPEND открывает его и добавляет данные в конец.READFILE name, variableчитает следующую строку.WRITEFILE name, valueзаписывает одну.CLOSEFILE nameзакрывает ее.EOF(name)истинно (TRUE), когда достигнут конец.- Сначала выберите структуру файлов и метод доступа: последовательные, последовательные и произвольные файлы служат разным операциям. Примеры здесь используют последовательный доступ к текстовым записям.
- Паттерн для чтения всего файла всегда одинаков:
OPENFILE "names.txt" FOR READ
WHILE NOT EOF("names.txt") DO
READFILE "names.txt", thisName
OUTPUT thisName
ENDWHILE
CLOSEFILE "names.txt"

Открыть, использовать, закрыть — каждый раз
Маршрут доступа к файлу
Безопасно следите за файлом от хранилища до программы и обратно.
Что делает открытие файла FOR WRITE с существующим содержимым?
WRITE создает или перезаписывает файл. Чтобы сохранить существующее содержимое и добавить больше, используйте APPEND.
Соотнесите каждую операцию с файлом с тем, что она делает.
WRITE перезаписывает, APPEND добавляет; EOF обозначает конец; цикл поиска останавливается раньше, как только значение найдено.
Поиск в файле
- Для поиска читайте построчно и остановитесь, когда целевая запись будет найдена. Необходимы два условия:
WHILE NOT EOF(…) AND NOT found. - Флаг
foundимеет значение. Без него цикл будет читать весь файл даже после совпадения, что расточительно, и после этого не останется ничего для проверки, чтобы сообщить «не найдено».
found ← FALSE
OPENFILE "names.txt" FOR READ
WHILE NOT EOF("names.txt") AND NOT found DO
READFILE "names.txt", thisName
IF thisName = target THEN
found ← TRUE
ENDIF
ENDWHILE
CLOSEFILE "names.txt"
При поиске значения в файле условие цикла обычно включает:
Остановка при нахождении avoids unnecessary reading of the rest of the file.
Почему цикл поиска в файле использует WHILE NOT EOF AND NOT found? Выберите все подходящие варианты.
Каждый файл все равно необходимо закрыть. Два условия отвечают за ранний выход и конец файла соответственно.
Обновление: паттерн временного файла
- Поскольку текстовый файл нельзя отредактировать на месте, обновление использует временный файл.
- Откройте оригинальный файл ДЛЯ ЧТЕНИЯ и временный файл ДЛЯ ЗАПИСИ. Читайте каждую строку последовательно; записывайте ее во временный файл либо измененной, либо без изменений.
- Закройте оба файла, затем замените оригинал временным файлом.
- Один и тот же паттерн делает всё: чтобы удалить запись, пропустите запись этой строки; чтобы вставить новую, запишите новую строку в нужном месте при копировании.
Для обновления текстового файла, когда редактирование на месте невозможно, вы:
Копируйте каждую строку (измененную или нет) во временный файл, затем замените ею оригинал.
Расставьте шаги удаления одной записи из текстового файла по порядку.
Последний шаг — это то, что кандидаты пропускают, и без него ничего не изменится. Тот же паттерн используется для вставки или редактирования записи.
Разобранное решение: удаление записи
- Опишите, как программа удаляет одну запись из текстового файла. [4]
- Откройте оригинальный файл для чтения и временный файл для записи.
- Читайте каждую строку последовательно. Если строка не является той, которую нужно удалить, запишите ее во временный файл; если является, не записывайте её.
- Когда будет достигнут конец оригинального файла, закройте оба файла.
- Замените оригинальный файл временным файлом. Все четыре шага оцениваются, и последний — это тот, который кандидаты забывают.
Программа записывает 500 записей, затем завершается без закрытия файла, и последние несколько отсутствуют. Почему?
Записи буферизируются для скорости. Закрытие файла сбрасывает буфер, а также может освободить блокировку, которую ожидают другие программы.
Ловушки
- Забыть закрыть файл: буферизированные данные могут никогда не быть записаны, поэтому последние записи исчезают, а файл может остаться заблокированным для других программ.
- Открытие ДЛЯ ЗАПИСИ вместо intended APPEND: все существующее содержимое уничтожается в момент открытия файла, до того как будет записана хотя бы одна строка.
- Чтение за пределами EOF: проверяйте
EOFперед каждым чтением, а не после. - Жестко заданные пути: поместите имя файла в константу, чтобы оно встречалось один раз и программу можно было переместить.
Забвение закрытия файла может привести к потере буферизированных записей и блокировке других программ — поэтому всегда следует закрывать файл после работы с ним.
Закрытие сбрасывает буферизированные данные на диск и освобождает блокировку — блок FINALLY хорошее место для гарантированного выполнения этого действия.
Чтобы добавить сегодняшние записи в журнал, который должен сохранять историю, откройте файл FOR ____.
WRITE уничтожил бы все предыдущие записи в момент открытия файла, еще до того, как была написана хотя бы одна строка.
Разобранное решение: какой режим
- Программа добавляет сегодняшние транзакции в текущий журнал, который должен сохранять свою историю. APPEND: WRITE уничтожил бы все предыдущие записи.
- Программа генерирует новый отчет каждую ночь, заменяя вчерашний. WRITE: создание или перезапись именно то, что требуется.
- Программа читает конфигурационный файл при запуске. READ.
- Режим выбирается в зависимости от того, что должно произойти с существующим содержимым: сохранить и дополнить, уничтожить или оставить без изменений.
Потерянные баллы
- Паттерн обновления завершается заменой оригинала временным файлом. Копирование без этого последнего шага ничего не изменит.
- Циклу поиска нужны оба условия,
NOT EOFиNOT found, и что-то для проверки после завершения. - WRITE перезаписывает; APPEND добавляет. Неправильный выбор уничтожает файл в момент открытия.
- Всегда
CLOSEFILE. Объясните почему: иначе могут потеряться буферизированные данные.
Вы поняли
OPENFILE … FOR READ | WRITE | APPEND, затемREADFILEилиWRITEFILE, затемCLOSEFILE;EOFпроверяется перед каждым чтением- WRITE создает или перезаписывает, APPEND сохраняет содержимое и добавляет в конец, READ начинает с начала
- поиск с
WHILE NOT EOF AND NOT found, чтобы цикл прервался раньше и можно было сообщить «не найдено» - обновление путем копирования через временный файл, запись каждой строки измененной или нет, пропуск строки для удаления или добавление одной для вставки, затем замена оригинала