摘要:Rust 标准库 std::io 提供统一的 I/O 抽象(Read/Write/Seek trait),支持 stdin/stdout/stderr、缓冲读写、文件复制;std::fs 负责文件系统操作(创建、读写、重命名、删除、遍历)。Path/PathBuf 处理跨平台路径,无需打开文件即可查询属性。所有操作统一返回 Result<T, io::Error>,配合 ? 运算符实现优雅错误传播。本文深入讲解 trait 多态、缓冲机制、路径转换及线程安全锁,帮助你高效处理文件、网络、控制台 I/O,写出生产级 Rust 程序。

一、io 模块 —— 基本操作与常用功能

专业名词释义

  • std::io:统一 I/O 接口模块,提供标准流、缓冲区、复制等功能,所有 I/O 操作返回 Result

用法示例(核心 API):

use std::io::{self, Write, Read, Result};

fn example() -> Result<()> {
    // 复制数据流
    let mut reader: &[u8] = b"hello";
    let mut writer: Vec<u8> = vec![];
    io::copy(&mut reader, &mut writer)?;

    // 标准输入/输出
    let mut buffer = String::new();
    io::stdin().read_line(&mut buffer)?;
    io::stdout().write_all(b"hello world")?;

    // 线程安全锁
    let mut locked = io::stdout().lock();
    locked.write_all(b"hello world")?;
    Ok(())
}

注意事项与最佳实践

  • stdout().lock() 返回写防护,离开作用域自动释放,防止多线程交错输出。
  • 深度提示io::copy 内部使用循环读写,直到 EOF;read_to_string 自动处理 UTF-8。
  • 最佳实践:生产环境始终用 ? 传播错误;大文件读写必须加 BufReader/BufWriter(减少系统调用)。

二、io 模块 —— 常用 trait(Read / Write / Seek)

专业名词释义

  • Read:从源读取字节(readread_to_endread_to_string)。
  • Write:向目标写入字节(writewrite_allflush)。
  • Seek:定位读取/写入位置(seek(SeekFrom::Start/End/Current))。

用法示例(File 同时实现三 trait):

use std::fs::File;
use std::io::{self, prelude::*, SeekFrom};

fn main() -> io::Result<()> {
    let mut f = File::open("foo.txt")?;
    let mut buffer = Vec::new();
    f.read_to_end(&mut buffer)?;           // Read

    let mut f = File::create("foo.txt")?;
    f.write_all(b"some bytes")?;           // Write

    let mut f = File::open("foo.txt")?;
    f.seek(SeekFrom::Start(42))?;          // Seek
    Ok(())
}

注意事项与最佳实践

  • FileTcpStreamStdin 等均实现这些 trait,实现“零成本抽象”。
  • 深度提示Write::flush 强制缓冲区落盘;SeekFrom::Current(0) 获取当前位置。
  • 最佳实践:自定义类型实现 Read/Write 可无缝接入 io::copy;大文件用 seek 随机访问。

三、fs 模块 —— 基本操作与常用功能

专业名词释义

  • std::fs:文件系统模块,提供创建/读写/重命名/删除/遍历等操作,全部返回 io::Result

用法示例

use std::fs::{self, File};

fn main() -> std::io::Result<()> {
    let mut f = File::create("foo.txt")?;
    f.write_all(b"hello world")?;

    fs::rename("foo.txt", "bar.txt")?;
    fs::remove_file("bar.txt")?;

    // 遍历目录
    for entry in fs::read_dir(".")? {
        let entry = entry?;
        if entry.path().is_dir() {
            println!("dir: {}", entry.path().display());
        }
    }
    Ok(())
}

注意事项与最佳实践

  • fs::metadatafs::symlink_metadata 可查询权限/大小/时间,无需打开文件。
  • 深度提示read_dir 返回 ReadDir 迭代器,配合 ? 优雅处理权限错误。
  • 最佳实践:批量操作用 fs::copy/fs::remove_dir_all;临时文件推荐 tempfile crate。

四、Path 与 PathBuf —— 跨平台路径处理

专业名词释义

  • Path:借用型,只读引用(&Path),无需打开文件即可查询属性。
  • PathBuf:拥有型,可变路径(PathBuf),支持 pushset_extension 等修改。

用法示例

use std::path::{Path, PathBuf};

let mut pb = PathBuf::new();
pb.push("C:");
pb.push("windows");
pb.push("system32");
pb.set_extension("dll");

let path = Path::new("hello.txt");
if path.is_file() {
    println!("{}", path.display());
}

注意事项与最佳实践

  • Path 跨平台(自动处理 / vs \);PathBuf 适合动态构建。
  • 深度提示path.display() 格式化输出,path.exists()path.is_dir() 零成本查询。
  • 最佳实践:函数参数永远用 &Path(更通用);字符串转路径用 Path::newPathBuf::from

五、PathBuf / Path 转换

用法示例

use std::path::{Path, PathBuf};

// Path → &str
let p: &Path = Path::new("/tmp/foo.txt");
let s: &str = p.to_str().unwrap();

// PathBuf → &Path
let pb: PathBuf = PathBuf::from("/test");
assert_eq!(Path::new("/test"), pb.as_path());

注意事项与最佳实践

  • to_str 返回 Option<&str>(非法 UTF-8 返回 None)。
  • 深度提示as_os_str 可获取原始 OS 字符串,处理非 UTF-8 路径。
  • 最佳实践:路径拼接用 PathBuf::push 避免手动字符串操作,防止平台差异。

本章小结 + 进阶练习

学完本章你应该能做到

  • 熟练使用 io::stdin/stdout + Read/Write/Seek trait
  • 掌握 fs 文件操作与 read_dir 遍历
  • 灵活运用 Path/PathBuf 构建与转换

进阶练习(建议立刻敲代码):

  1. BufReader + ? 实现一个高效的 cat 命令(支持多个文件)。
  2. 写一个递归遍历目录函数,统计所有 .rs 文件行数。
  3. 实现 copy_file(src: &Path, dst: &Path),处理 io::Error 并打印自定义信息。
  4. PathBuf 动态构建跨平台临时文件路径(结合 std::env::temp_dir)。
  5. 自定义类型实现 Read + Write,接入 io::copy 测试(可选扩展)。

io + fs + Path = Rust 文件操作的基石。掌握 trait 抽象与路径处理,你就能轻松实现日志、配置、数据持久化等功能,真正进入 Rust 工程化阶段!

(完)

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐