概述
任何一门编程语言中 IO 操作都是非常常见的内容. IO 操作抽象了对实体的读写,该实体可以是任意类型,比如文件,内存,或者 Socket。
典型的 IO 操作包含 读写操作, 大多数编程语言还会提供基于字符串的读写, 和基于缓冲的读写以提高性能
Rust IO 操作简介 2024-04-09 21:09·逍遥游 任何一门编程语言中 IO 操作都是非常常见的内容. IO 操作抽象了对实体的读写,该实体可以是任意类型,比如文件,内存,或者 Socket。
典型的 IO 操作包含 读写操作, 大多数编程语言还会提供基于字符串的读写, 和基于缓冲的读写以提高性能
以 Java 为例,Java 中定义了 InputStream/OutputStream 接口,包含一序列读写二进制的方法。
Reader/Writer 则 提供了操作字符串的方法
BufferedInputStream/BufferedOutputStream,BufferedReader/BufferedWriter 提供了基于缓冲的读写
Rust 也对 IO 操作提供了丰富的支持,位于 std::io 包下面
Rust 标准库中的 IO 操作类主要有
Read/Write, BufRead trait
BufReader/BufWriter struct
相比于 Java, 个人认为 Rust 的 IO 标准库 API 设计明显缺乏对称性和美感
比如说 Read trait 中包含了对字节类型的读方法,也包含了直接读字符串的方法
但作为 对应的 Write trait, 却只有对字节类型的写方法,而没有写字符串的方法
另外读方面有 BufRead trait, 但写的却没有 BufWrite trait
总体感觉 API 设计明显不如 Java 清晰
*** Rust 标准库中,IO 的具体实现有 File,Cursor (实现了 BufRead), 和 TcpStream ***
下面是个例子
use std::io;
use std::io::prelude::*;
use std::fs::File;
fn main() -> io::Result<()> {
let mut f = File::open("foo.txt")?;
let mut buffer = [0; 10];
// read up to 10 bytes
let n = f.read(&mut buffer)?;
println!("The bytes: {:?}", &buffer[..n]);
Ok(())
}
*** 对于 BufWriter 来说,需要注意 2 点 ***
-
BufWriter 对于内存的读写没有任何优势,这时可以直接用 Write. 只对多次分批写入非内存对象时,有性能优势。
-
在 BufWriter 被 drop 之前,需要手动的调用 flush, 以确保数据已经写入。因为 BufWriter 被 drop 时,虽然也会调用 flush,但如果 flush 失败,rust 是不会有任何错误通知的。
使用 BufWriter 的例子
第一种,不使用BufWriter, 性能会比较差
use std::io::prelude::*;
use std::net::TcpStream;
let mut stream = TcpStream::connect("127.0.0.1:34254").unwrap();
for i in 0..10 {
stream.write(&[i+1]).unwrap();
}
第二种, 使用BufWriter, 性能会好很多
use std::io::prelude::*;
use std::io::BufWriter;
use std::net::TcpStream;
let mut stream = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
for i in 0..10 {
stream.write(&[i+1]).unwrap();
}
stream.flush().unwrap();
Rust 标准库非常的小,没有提供基于内存实现的 Read/Write, 只能跑去第三方 crate Bytes 了
该 crate 自己定义了一组 Read/Write, Reader/Writer,方便操作内存数据
use bytes::Buf;
use std::io;
let mut buf = b"hello world".reader();
let mut dst = vec![];
io::copy(&mut buf, &mut dst).unwrap();
let buf = buf.into_inner();
assert_eq!(0, buf.remaining());
「真诚赞赏,手留余香」
真诚赞赏,手留余香
使用微信扫描二维码完成支付
![](/img/reward/wechat-2.png)