系统编程

第17课:文件IO

🎯 本课目标

掌握Rust文件读写、目录操作、标准IO和路径处理。

1. 文件读写

use std::fs::{File, OpenOptions};
use std::io::{Read, Write, BufReader, BufWriter};

fn main() -> std::io::Result<()> {
    // 一次性读取
    let content = std::fs::read_to_string("input.txt")?;

    // 一次性写入
    std::fs::write("output.txt", "Hello, file!")?;

    // 缓冲读取
    let file = File::open("input.txt")?;
    let mut reader = BufReader::new(file);
    let mut buf = [0; 1024];
    let n = reader.read(&mut buf)?;

    // 缓冲写入
    let file = File::create("output.txt")?;
    let mut writer = BufWriter::new(file);
    writer.write_all(b"Hello")?;
    writer.flush()?;

    // 高级选项
    let file = OpenOptions::new()
        .read(true)
        .write(true)
        .create(true)
        .append(true)
        .open("log.txt")?;

    // 逐行读取
    use std::io::BufRead;
    let file = File::open("input.txt")?;
    for line in BufReader::new(file).lines() {
        println!("{}", line?);
    }

    Ok(())
}

✅ 编译验证通过

2. 目录操作

use std::fs;
use std::path::Path;

fn main() -> std::io::Result<()> {
    // 创建目录
    fs::create_dir("test_dir")?;
    fs::create_dir_all("test_dir/sub/deep")?;

    // 遍历目录
    for entry in fs::read_dir(".")? {
        let entry = entry?;
        let path = entry.path();
        if path.is_dir() {
            println!("[DIR] {:?}", path);
        } else {
            println!("[FILE] {:?}", path);
        }
    }

    // 路径操作
    let path = Path::new("/home/user/file.txt");
    println!("父目录: {:?}", path.parent());
    println!("文件名: {:?}", path.file_name());
    println!("扩展名: {:?}", path.extension());

    // 文件元数据
    let meta = fs::metadata("input.txt")?;
    println!("大小: {} bytes", meta.len());

    Ok(())
}

✅ 编译验证通过

3. 标准IO

use std::io;

fn main() -> io::Result<()> {
    // 读取一行
    let mut input = String::new();
    io::stdin().read_line(&mut input)?;
    println!("输入: {}", input.trim());

    // 锁定stdin提高性能
    let stdin = io::stdin();
    let mut handle = stdin.lock();
    for line in handle.lines() {
        println!("{}", line?);
    }

    Ok(())
}

✅ 编译验证通过

4. 文件IO的内存模型

BufReader工作原理: 无缓冲: 磁盘 → 内核缓冲区 → 用户空间1字节 → 程序 每次read系统调用! 有缓冲(默认8KB): 磁盘 → 内核缓冲区 → BufReader缓冲区(8KB) → 程序 一次系统调用读取8KB,减少系统调用次数 ┌────────────────┐ │ 用户程序 │ │ ↓ read() │ │ BufReader │ │ ┌────────────┐ │ │ │ 8KB 缓冲区 │ │ ← 一次填充,多次读取 │ └────────────┘ │ │ ↓ syscall │ │ 内核 │ │ ↓ DMA │ │ 磁盘 │ └────────────────┘

📝 练习题

练习1:文件搜索

递归搜索目录中包含关键字的文件。

练习2:文件复制

实现带进度显示的文件复制。

练习3:CSV处理

读写CSV文件,支持过滤和排序。

🏆

成就解锁:文件管家

掌握Rust文件IO——与外部世界交互

🔬 深度理解:Rust与系统编程

系统编程的核心挑战是在不牺牲安全的前提下获得最大性能。Rust如何实现这个目标:

1. 无GC的内存管理

所有权系统在编译期确定每个值的生命周期,不需要运行时垃圾回收。这意味着:无停顿、可预测延迟、更少内存占用。

2. 零成本抽象到硬件

泛型单态化、内联、LLVM优化——高级代码编译为与手写C相当的机器码。

3. 并发无数据竞争

Send/Sync trait在编译期保证:如果是并发访问,要么只读,要么互斥。数据竞争不可能发生。

📊 Rust vs C/C++对比

特性RustCC++
内存安全✅ 编译期❌ 手动⚠️ 部分RAII
线程安全✅ 编译期
无GC
零成本抽象⚠️ 宏✅ 模板
包管理✅ Cargo⚠️ vcpkg
学习曲线陡峭中等极陡

🛡️ 安全编码实践

即使Rust保证内存安全和线程安全,仍需注意:

Rust系统编程课程 · 第17课 · 2026

📚 扩展阅读

以下资源帮助你深入学习本课主题:

  • The Rust Programming Language — 官方教程,Rust圣经
  • Rust by Example — 通过示例学习Rust
  • Rust Reference — 语言参考手册
  • Rustnomicon — Unsafe Rust黑魔法指南
  • Too Many Lists — 用Rust实现各种链表

🔑 关键术语回顾

本课涉及的核心概念,确保你理解每一个:

术语说明
所有权Rust内存管理的核心机制,每个值有唯一所有者
借用通过引用访问数据,不获取所有权
生命周期引用有效的范围,编译期分析工具
traitRust的接口/抽象机制,类似其他语言的接口
泛型参数化类型,零成本抽象
模式匹配强大的数据解构和分支机制
零成本抽象高层抽象不引入运行时开销
fearless concurrency编译器保证线程安全

💬 学习建议

  1. 动手编码 — 每个代码示例都在本地运行一遍
  2. 修改实验 — 故意改错代码,看编译器报什么错
  3. 完成练习 — 每课的练习题是巩固知识的关键
  4. 阅读源码 — 看标准库和优秀开源项目的实现
  5. 写项目 — 真正掌握需要构建真实项目

🤔 常见问题

Q: Rust学习曲线真的很陡吗?

A: 前期确实需要适应所有权和借用检查器,但一旦理解了,这些概念会让你的代码更可靠。大多数人2-4周就能上手。

Q: Rust适合什么项目?

A: 系统编程、Web服务、CLI工具、嵌入式、WASM、网络服务、数据库等。基本上需要性能和安全的地方都适合。

Q: 遇到编译错误怎么办?

A: Rust编译器的错误信息非常友好!仔细阅读,通常会指出问题所在和修复建议。也可以用cargo clippy获取更多提示。