Ch 20: Write trait
Write是Rust中用于写入字节流的trait。与Read相对,Write trait用于所有输出目标:
File- 文件TcpStream- TCP socketstd::io::stdout- 标准输出Vec<u8>- 内存缓冲区
Write trait同样定义在std::io模块中。
2. Write trait定义
Section titled “2. Write trait定义”pub trait Write { fn write(&mut self, buf: &[u8]) -> Result<usize>;
fn write_all(&mut self, buf: &[u8]) -> Result<()>;
fn flush(&mut self) -> Result<()>;
// 其他方法...}3. write方法
Section titled “3. write方法”write是最基本的写入方法:
use std::io::{Write, Cursor};
fn main() -> std::io::Result<()> { let mut cursor = Cursor::new(Vec::new());
// write 返回写入的字节数(可能少于请求的) let n = cursor.write(b"hello")?; println!("write返回: {} 字节", n);
// 获取写入的内容 println!("cursor内容: {:?}", cursor.get_ref());
Ok(())}注意:write可能返回比请求更少的字节,调用者需要处理这种情况。
4. write_all方法
Section titled “4. write_all方法”写入所有数据:
use std::io::{Write, Cursor};
fn main() -> std::io::Result<()> { let mut cursor = Cursor::new(Vec::new());
// write_all 确保写入所有数据 cursor.write_all(b"hello world")?; cursor.write_all(b"!")?;
println!("写入内容: {:?}", cursor.get_ref()); // 输出: [104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33]
Ok(())}5. flush方法
Section titled “5. flush方法”将缓冲区数据刷新到实际目标:
use std::io::{Write, Cursor};
fn main() -> std::io::Result<()> { let mut cursor = Cursor::new(Vec::new());
cursor.write_all(b"hello")?;
// flush 确保数据被写出 cursor.flush()?;
println!("flush完成");
Ok(())}重要:对于文件和网络连接,flush之前数据可能还在缓冲区。
6. 格式化写入
Section titled “6. 格式化写入”use std::io::Write;
fn main() -> std::io::Result<()> { let mut stdout = std::io::stdout();
// writeln! 格式化写入并换行 writeln!(stdout, "Hello, {}!", "world")?; writeln!(stdout, "数字: {}, 字符: {}", 42, 'A')?;
stdout.flush()?;
Ok(())}7. BufWriter缓冲写入
Section titled “7. BufWriter缓冲写入”BufWriter包装Writer,提供写入缓冲:
use std::io::{Write, BufWriter, Cursor};
fn main() -> std::io::Result<()> { let file = File::create("output.txt")?; let mut buffered = BufWriter::new(file);
// 多次小写入会被缓冲 for i in 0..1000 { writeln!(buffered, "行 {}", i)?; }
// drop或flush时数据被写出 buffered.flush()?;
println!("写入完成");
Ok(())}8. write_fmt格式化
Section titled “8. write_fmt格式化”use std::io::Write;
fn main() -> std::io::Result<()> { let mut stdout = std::io::stdout();
// write_fmt 使用格式化宏 stdout.write_fmt(format_args!("{:#?}", [1, 2, 3]))?; stdout.write_all(b"\n")?;
stdout.flush()?;
Ok(())}9. set_write_capacity设置缓冲大小
Section titled “9. set_write_capacity设置缓冲大小”use std::io::{BufWriter, BufWriter, File};
fn main() -> std::io::Result<()> { let file = File::create("large_output.txt")?; let mut writer = BufWriter::new(file);
// 设置更大的缓冲区 writer.get_ref();
// 写入大量数据 for i in 0..10000 { writeln!(writer, "数据行 {}", i)?; }
writer.flush()?;
Ok(())}10. into_inner获取底层Writer
Section titled “10. into_inner获取底层Writer”use std::io::{Write, BufWriter, Cursor};
fn main() -> std::io::Result<()> { let mut cursor = Cursor::new(Vec::new()); let mut writer = BufWriter::new(&mut cursor);
writer.write_all(b"hello")?; writeln!(writer, " world")?;
// into_inner 获取底层Writer // 注意:需要先flush writer.flush()?; let inner = writer.into_inner().unwrap();
println!("inner: {:?}", inner.get_ref());
Ok(())}11. 实现Write trait
Section titled “11. 实现Write trait”use std::io::{self, Write};
struct Counter { count: usize,}
impl Write for Counter { fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.count += buf.len(); Ok(buf.len()) }
fn flush(&mut self) -> io::Result<()> { Ok(()) }}
fn main() -> io::Result<()> { let mut counter = Counter { count: 0 }; counter.write_all(b"hello")?; counter.write_all(b" world")?; println!("写入的字节数: {}", counter.count); Ok(())}12. 常见Write实现者
Section titled “12. 常见Write实现者”| 类型 | 说明 |
|---|---|
File | 文件 |
TcpStream | TCP连接 |
BufWriter<T> | 带缓冲的写入器 |
std::io::stdout | 标准输出 |
std::io::stderr | 标准错误 |
Vec<u8> | 内存缓冲区 |
13. 错误处理模式
Section titled “13. 错误处理模式”use std::io::Write;
fn main() -> std::io::Result<()> { let mut stdout = std::io::stdout();
// write返回Result,需要处理 match stdout.write(b"hello") { Ok(n) => println!("写入 {} 字节", n), Err(e) => eprintln!("写入错误: {}", e), }
// 通常使用?操作符传播错误 stdout.write_all(b" world")?;
stdout.flush()?;
Ok(())}14. 总结
Section titled “14. 总结”今天我们学习了Write trait:
- write - 写入数据到缓冲区,返回写入字节数
- write_all - 确保写入所有数据
- flush - 刷新缓冲区到目标
- BufWriter - 包装Writer提供缓冲,减少系统调用
- writeln! - 格式化写入并换行
- write_fmt - 格式化参数写入
Write trait是Rust I/O系统的重要组成部分,正确使用flush和BufWriter可以显著提高写入性能。