Ch 19: Read trait
Read是Rust中用于读取字节流的trait。所有表示输入源的类型都实现了这个trait:
File- 文件TcpStream- TCP socketstd::io::stdin- 标准输入Cursor<&[u8]>- 内存中的字节切片Vec<u8>- 实现了Read用于读取
Read trait定义了在std::io模块中,是Rust I/O系统的核心。
2. Read trait定义
Section titled “2. Read trait定义”pub trait Read { fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize>;
fn read_to_string(&mut self, buf: &mut String) -> Result<usize>;
// 还有其他方法...}3. read方法
Section titled “3. read方法”read是最基本的读取方法,将数据读入缓冲区:
use std::io::{Read, Cursor};
fn main() -> std::io::Result<()> { let data = b"hello world"; let mut cursor = Cursor::new(data);
let mut buffer = [0u8; 1024];
// read 返回读取的字节数 let n = cursor.read(&mut buffer)?; println!("读取了 {} 字节", n); println!("内容: {:?}", &buffer[..n]);
Ok(())}注意:read可能返回比请求的更少的字节(例如网络读取)。
4. read_to_end方法
Section titled “4. read_to_end方法”将所有剩余数据读入Vec:
use std::io::{Read, Cursor};
fn main() -> std::io::Result<()> { let data = b"hello world"; let mut cursor = Cursor::new(data);
let mut vec = Vec::new(); cursor.read_to_end(&mut vec)?;
println!("读取到Vec: {:?}", vec); println!("字符串: {}", String::from_utf8_lossy(&vec));
Ok(())}5. read_to_string方法
Section titled “5. read_to_string方法”直接读取到String:
use std::io::{Read, Cursor};
fn main() -> std::io::Result<()> { let data = b"hello world"; let mut cursor = Cursor::new(data);
let mut s = String::new(); cursor.read_to_string(&mut s)?;
println!("字符串: {}", s);
Ok(())}6. read_line方法
Section titled “6. read_line方法”Read本身没有read_line,它是在BufRead trait中提供的。我们将在下一章学习。
7. bytes方法
Section titled “7. bytes方法”返回字节迭代器:
use std::io::{Read, Cursor};
fn main() -> std::io::Result<()> { let data = b"hello"; let mut cursor = Cursor::new(data);
// bytes 返回迭代器 for byte in cursor.bytes() { print!("{} ", byte?); } println!(); // 输出: 104 101 108 108 111
Ok(())}8. 读取固定大小
Section titled “8. 读取固定大小”use std::io::{Read, Cursor};
fn main() -> std::io::Result<()> { let data = b"hello world"; let mut cursor = Cursor::new(data);
// read_exact 读取精确字节数 let mut buffer = [0u8; 5]; cursor.read_exact(&mut buffer)?;
println!("read_exact: {:?}", buffer); println!("字符串: {}", String::from_utf8_lossy(&buffer));
Ok(())}如果数据不足,read_exact会返回错误。
9. take限制读取量
Section titled “9. take限制读取量”use std::io::{Read, Cursor};
fn main() -> std::io::Result<()> { let data = b"hello world"; let mut cursor = Cursor::new(data);
// take 限制读取的字节数 let mut limited = cursor.take(5); let mut buffer = [0u8; 1024]; let n = limited.read(&mut buffer)?;
println!("读取了 {} 字节: {:?}", n, &buffer[..n]);
Ok(())}10. 链式读取器
Section titled “10. 链式读取器”use std::io::{Read, Cursor};
fn main() -> std::io::Result<()> { let data1 = b"hello"; let data2 = b" world";
let mut cursor1 = Cursor::new(data1); let mut cursor2 = Cursor::new(data2);
let mut combined = cursor1.chain(cursor2);
let mut buffer = [0u8; 1024]; let n = combined.read(&mut buffer)?;
println!("chain读取: {:?}", String::from_utf8_lossy(&buffer[..n])); // 输出: chain读取: "hello world"
Ok(())}11. 实战示例:读取文件
Section titled “11. 实战示例:读取文件”use std::fs::File;use std::io::{Read, BufReader};
fn main() -> std::io::Result<()> { let file = File::open("Cargo.toml")?; let mut reader = BufReader::new(file);
let mut contents = String::new(); reader.read_to_string(&mut contents)?;
println!("文件内容 (前100字符):"); for line in contents.lines().take(5) { println!("{}", line); }
Ok(())}12. 错误处理
Section titled “12. 错误处理”use std::io::{Read, Cursor};
fn main() { let data: &[u8] = &[]; let mut cursor = Cursor::new(data);
let mut buffer = [0u8; 1024];
// read返回Result match cursor.read(&mut buffer) { Ok(n) => println!("读取了 {} 字节", n), Err(e) => println!("读取错误: {}", e), }
// read_to_end同样返回Result let mut vec = Vec::new(); if let Err(e) = cursor.read_to_end(&mut vec) { println!("read_to_end错误: {}", e); }}13. Read实现者
Section titled “13. Read实现者”| 类型 | 说明 |
|---|---|
File | 文件 |
TcpStream | TCP连接 |
BufReader<T> | 带缓冲的读取器 |
Cursor<T> | 内存中的数据 |
std::io::stdin | 标准输入 |
Chain<T, U> | 链式读取器 |
Take<T> | 限制读取量 |
14. 总结
Section titled “14. 总结”今天我们学习了Read trait:
- read - 将数据读入缓冲区,返回读取字节数
- read_to_end - 读取所有剩余数据到Vec
- read_to_string - 直接读取到String
- read_exact - 读取精确字节数
- bytes - 返回字节迭代器
- take - 限制读取量
- chain - 链式连接两个读取器
Read是Rust I/O的基础trait,理解它的用法对文件操作、网络编程等场景至关重要。