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

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

Выберите одноразовую операцию 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(path: string) -> Result<File, string>
file.read() -> Result<string, string>
file.write(text: string) -> Result<(), string>
file.close() -> ()

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

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

Создайте note.txt с текстом ready, затем сохраните программу как files-resources.tpz:

TOPAZ
function readNote(path: string) -> Result<string, string> {
    let mut result: Result<string, string> = Err("not read")
    using file = open(path)? {
        result = file.read()
    }
    return result
}

match readNote("note.txt") {
    case Ok(text) => print(text.trim())
    case Err(error) => print(error)
}
Вывод
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 и ошибки или обзора стандартной библиотеки.