Доступ к файлам пересекает явную границу со средой. Если задача завершается
одним вызовом, выберите операцию FS. Если несколько чтений или записей
должны использовать один открытый ресурс, выберите File с видимым временем
жизни.
Выберите FS или File
| Задача | Что использовать | Точный результат |
|---|---|---|
| Прочитать текстовый файл одним вызовом | FS.readText(path) | Result<string, string> |
| Заменить содержимое текстового файла одним вызовом | FS.writeText(path, text) | Result<(), string> |
| Прочитать или записать неизменяемые байты | FS.readBytes, FS.writeBytes | Result<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:
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)
}readyopen может завершиться до создания 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 и ошибки или обзора стандартной библиотеки.