Доступ к файлам пересекает явную границу со средой исполнения. Если задача решается за один вызов, выберите операцию 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(путь: 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:
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 и ошибки или обзора стандартной библиотеки.