Стандартная библиотека и среда

Файлы и ресурсы

Читайте и записывайте файлы, обрабатывайте ошибки через Result и закрывайте открытый File с помощью using или defer.

Используйте FS для чтения или записи файла целиком, а File для нескольких операций с одним открытым файлом. Обрабатывайте ошибки через Result и задавайте момент закрытия с помощью using или defer.

Установите Топаз по инструкции «Первая программа». Окружение, запускающее программу, должно разрешать доступ к файловой системе. Импорт модуля не даёт этого разрешения.

Откройте и прочитайте один File

В рабочем каталоге создайте файл note.txt в UTF-8 с текстом ready. Рядом сохраните программу как files-resources.tpz.

TOPAZ
function прочитатьЗаметку(путь: string) -> Result<string, string> {
    let mut результат: Result<string, string> = Err("not read")
    using файл = open(путь)? {
        результат = файл.read()
    }
    return результат
}

match прочитатьЗаметку("note.txt") {
    case Ok(текст) => print(текст.trim())
    case Err(ошибка) => print(ошибка)
}

Из этого каталога выполните topaz run files-resources.tpz.

Вывод
ready

При успешном открытии open возвращает Ok(файл). При неудаче ? возвращает ошибку из прочитатьЗаметку до входа в блок.

После открытия using создаёт привязку файл и регистрирует вызов close. Вызов файл.read() сохраняет свой Result во внешней переменной. При выходе из блока файл закрывается, затем функция возвращает сохранённый результат.

Если note.txt отсутствует, программа выводит ошибку от open. Восстановите файл в рабочем каталоге и запустите программу снова. Ветка Err выводит строку ошибки, поэтому программа может завершиться успешно даже при неудачном чтении.

Выберите FS или File

ЗадачаВызовТип результата
Прочитать весь текстFS.readText(path)Result<string, string>
Заменить весь текстFS.writeText(path, text)Result<(), string>
Прочитать все байтыFS.readBytes(path)Result<Bytes, string>
Заменить все байтыFS.writeBytes(path, bytes)Result<(), string>
Получить содержимое каталогаFS.list(path)Result<Array<{ kind: string, name: string, sizeBytes: Option<int> }>, string>
Оставить файл открытымopen(path)Result<File, string>

FS принимает Path или string. Операции записи заменяют содержимое файла. Выберите новый путь или сохраните копию перед перезаписью нужных данных.

Для открытого File доступны следующие вызовы.

open(path: string) -> Result<File, string>
файл.read() -> Result<string, string>
файл.write(s: string) -> Result<(), string>
файл.close() -> ()

Открывайте файл через open, а для текста используйте read или write. Для двоичного файла целиком выбирайте байтовые операции FS. Методов File.open, File.create, File.append, readLine, writeLine и flush нет.

Выберите using или defer

Где нужен файлКак закрыть
Внутри одного блокаusing файл = open(путь)? { ... } закрывает его при выходе из блока
В нескольких вложенных блоках функцииСразу после let файл = open(путь)? зарегистрируйте defer { файл.close() }

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

Обе формы освобождают ресурс при обычном выходе и выходах через return, постфиксный ?, break или continue. Ошибка выполнения (fault) немедленно останавливает программу. Освобождение ресурсов после такой ошибки не определено.

Доступ к файлам и поддерживаемые операции

  • File, FS, std.fs и std.io требуют профиля с доступом к файловой системе. Профиль задаёт доступные программе операции.
  • Импорт модуля не даёт доступа к путям, переменным окружения, процессам, сети или базам данных.
  • Открытие, чтение и запись возвращают ошибки как значения Err. Обрабатывайте их через match или передавайте дальше через ?.
  • File скрывает внутреннее состояние и не поддерживает сравнение. Не используйте его после закрытия.
  • Для File.write нет общего для всех сред режима дозаписи. Двоичные перегрузки, буферизация, управление правами и построчные методы File не определены.
  • using работает с одним File. Пользовательские протоколы освобождения, несколько ресурсов в using, асинхронная очистка, очистка при отмене и выходе из модуля не поддерживаются.

Порядок освобождения описан в разделе «Defer и ресурсы», передача ошибок в разделе Null, Option, Result и ошибки. Другие задачи ищите в обзоре стандартной библиотеки.