Rust 文件系统操作
std::fs 与 Path/PathBuf 的文件读写、目录与错误处理要点。
#concept
#growing
#dev
#rust
[!info] related notes
Rust 文件系统操作
这个概念为什么出现
配置、模板、数据文件都落在文件系统。
需要可移植的路径类型与清晰的错误上下文。
[!abstract] 一句话理解
Path/PathBuf表示路径;std::fs提供读写与目录操作;错误带路径上下文;注意 TOCTOU 与权限。
最小可运行示例
场景:读取应用配置文件文本
use std::fs;
use std::path::Path;
// 业务意图:读取配置文本;失败带路径。
// 教学点:Path;read_to_string;错误映射。
fn load_text(path: &Path) -> Result<String, String> {
fs::read_to_string(path).map_err(|e| format!("read {}: {e}", path.display()))
}
fn main() -> Result<(), String> {
let path = std::env::args_os().nth(1)
.ok_or_else(|| "usage: cargo run -- <config-path>".to_string())?;
let text = load_text(Path::new(&path))?;
print!("{text}");
Ok(())
}
先准备内容为 log=info 的配置文件,再运行 cargo run -- /path/to/config.txt。程序只读取指定文件,成功输出其内容;缺少参数或读取失败时非零退出,不创建、覆盖或删除固定文件名。
结合场景再看三个关注点
display()打印路径- 错误上下文
- 二进制用
fs::read
核心概念
Path非 UTF-8 可能(OsStr)create_dir_all、read_dirOpenOptions精细打开- metadata 跟随符号链接,symlink_metadata 检查链接自身
- read_to_string 读完整文件并验证 UTF-8,大文件或不可信输入应限制读取量
- fs::write / File::create 会截断已有文件;只允许新建时用 OpenOptions::create_new(true),不要先 exists 再创建
- display 是用于人读的可能有损显示,不应把它重新解析为权威路径
工程实践
- 路径别手拼字符串
- 临时文件可用 tempfile crate;std::env::temp_dir 只给目录,不负责原子创建、唯一命名或自动清理
- 权限与符号链接安全
- 大文件流式读
本节总结
- Path + fs
- 错误上下文
- 可移植意识
自测题
Path与String路径差别?- 为何避免“先 exists 再 open”作为安全检查?
参考答案
- Path 处理 OS 路径语义与非 UTF8。
- TOCTOU 竞态;应直接 open 并处理错误。
延伸阅读与资料来源
| 资料 | 类型 | 支撑内容 |
|---|---|---|
| std::fs | 标准库 | 文件系统 |
| std::path | 标准库 | 路径 |