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

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

Выберите однократную операцию FS или File с явным временем жизни, после чего обработайте Result и освобождение ресурсов.

Доступ к файлам пересекает явную границу со средой исполнения. Если задача решается за один вызов, выберите операцию FS. Если несколько операций чтения или записи должны использовать один открытый ресурс, выберите File с явным временем жизни.

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

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

Вызовы FS принимают Path | string. Интерфейс с явным временем жизни намеренно компактнее:

open(путь: string) -> Result<File, string>
файл.read() -> Result<string, string>
файл.write(текст: string) -> Result<(), string>
файл.close() -> ()

Канонические методы File.open, File.create, File.append, readLine, writeLine и flush отсутствуют.

Прочитайте один управляемый File

Создайте note.txt с текстом 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(ошибка)
}
Вывод
ready

Вызов open может завершиться с ошибкой до создания File, поэтому возвращает Result. Постфиксный ? передаёт ошибку до регистрации освобождения. После успешного получения using создаёт одну неизменяемую привязку File во вложенной области видимости и регистрирует один неявный close. Результат чтения переносится во внешнюю изменяемую привязку до закрытия области видимости.

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

  • Предпочитайте using file = open(path)? { ... }, когда один блок владеет ровно одним File. Время жизни открытой привязки не выходит за пределы вложенной области видимости.
  • Используйте let file = open(path)? и сразу defer { file.close() }, когда владеющей функции нужен File в нескольких вложенных блоках.
  • Явный file.close() внутри using не отменяет зарегистрированное закрытие. Поведение при повторном закрытии не является переносимым.

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

Частая ошибка: не воспринимайте file.write как запись с дозаписью в конец. Режимы дозаписи, бинарные перегрузки File, буферизация, права доступа и построчные методы File не входят в переносимый контракт. Для бинарного файла целиком используйте точные байтовые операции FS.

Границы возможностей и значений

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

Продолжите с Defer и ресурсами, Null, Option, Result и ошибки или обзора стандартной библиотеки.