跳到主要内容

IO 操作

问题

Rust 的 IO 模型是怎样的?Read/Write trait 如何使用?

答案

Rust 的 IO 基于 std::io 模块中的两个核心 trait:ReadWrite

Read 与 Write

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

fn main() -> io::Result<()> {
// === 读取文件 ===
// 方式 1:一次性读取全部内容
let content = std::fs::read_to_string("input.txt")?;

// 方式 2:缓冲读取(推荐大文件)
let file = File::open("input.txt")?;
let reader = BufReader::new(file);
for line in reader.lines() {
println!("{}", line?);
}

// === 写入文件 ===
// 方式 1:一次性写入
std::fs::write("output.txt", "hello")?;

// 方式 2:缓冲写入(推荐大量写入)
let file = File::create("output.txt")?;
let mut writer = BufWriter::new(file);
writer.write_all(b"hello world")?;
// BufWriter 在 drop 时自动 flush

Ok(())
}

核心 trait 关系

Trait作用关键方法
Read字节读取read(), read_to_string(), read_exact()
Write字节写入write(), write_all(), flush()
BufRead缓冲读取read_line(), lines(), fill_buf()
Seek随机访问seek(), stream_position()

泛型 IO:面向 trait 编程

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

/// 接受任何实现了 Read 的类型
fn count_bytes(mut reader: impl Read) -> io::Result<usize> {
let mut buf = Vec::new();
reader.read_to_end(&mut buf)?;
Ok(buf.len())
}

// 可以传文件、网络流、内存 Cursor 等
let bytes = count_bytes(File::open("test.txt")?)?;
let bytes = count_bytes(std::io::Cursor::new(b"hello"))?;
let bytes = count_bytes(&b"raw bytes"[..])?;
实践建议
  • 小文件用 fs::read_to_string / fs::write
  • 大文件用 BufReader / BufWriter
  • 函数参数用 impl Read / impl Write 提高通用性

常见面试问题

Q1: 为什么需要 BufReader/BufWriter?

答案

直接使用 Read/Write 每次操作都是系统调用(syscall),开销大。BufReader/BufWriter 在内存中维护缓冲区,减少系统调用次数,显著提升性能。默认缓冲区 8KB。

Q2: Cursor 有什么用?

答案

std::io::Cursor<T> 为内存中的字节切片提供 Read/Write/Seek 实现,常用于测试(不需要真实文件)和内存中的 IO 操作。

相关链接