Struct std::io::BufWriter
pub struct BufWriter<W: Write> { /* private fields */ }包装一个 writer 并缓冲其输出。
直接与实现 Write 的组件一起工作可能会非常低效。 例如,对 TcpStream 上 write 的每次调用都会导致系统调用。 BufWriter<W> 保留数据的内存缓冲区,并以大批量、不频繁的方式将其写入底层 writer。
BufWriter<W> 可以提高对同一文件或网络套接字进行小规模重复写调用的程序的速度。 一次写入大量或一次写入几次都无济于事。 在写入内存中的目标时,它也没有提供任何优势,例如 Vec<u8>.
在丢弃 BufWriter<W> 之前,调用 flush 至关重要。 尽管丢弃将尝试刷新缓冲区的内容,但丢弃过程中发生的任何错误都将被忽略。 调用 flush 可确保缓冲区为空,因此丢弃操作甚至不会尝试文件操作。
Examples
让我们将数字 1 到 10 写入 TcpStream:
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<W>:
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();通过用 BufWriter<W> 包装流,这十次写操作全部由缓冲区分组,并且在刷新 stream 时将全部写在一个系统调用中。
Implementations
impl<W: Write> BufWriter<W>
new
创建一个具有默认缓冲区容量的新 BufWriter<W>。 当前默认值为 8 KB,但可能会在 future 中进行更改。
给一个“写目标”套上一层内存缓冲区,减少系统调用,提高写入性能。
pub fn new(inner: W) -> BufWriter<W>参数:
- inner:真正要写的地方(如 File、Vec<u8>、TcpStream)
返回值:返回一个具有默认缓冲区容量的新 BufWriter
向一个文件写入内容
use std::fs::OpenOptions;
use std::io::{BufWriter, Write};
fn main() {
let file = OpenOptions::new()
.create(true)
.append(true)
.open("test.txt")
.unwrap();
let mut writer = BufWriter::new(file);
let res = writer.write_all(b"你冲QB嘛");
println!("{:#?}", res)
}获取缓冲区容量
use std::fs::OpenOptions;
use std::io::{BufWriter, Write};
fn main() {
let file = OpenOptions::new()
.create(true)
.append(true)
.open("test.txt")
.unwrap();
let writer = BufWriter::new(file);
println!("{:#?}", writer.capacity()) // 8192
}with_capacity
创建一个至少具有指定缓冲区容量的新 BufWriter<W>。
pub fn with_capacity(capacity: usize, inner: W) -> BufWriter<W>参数:
- capacity:指定的容量
- inner:真正要写的地方(如 File、Vec<u8>、TcpStream)
返回值:返回一个具有指定缓冲区容量的新 BufWriter
use std::fs::OpenOptions;
use std::io::{BufWriter, Write};
fn main() {
let file = OpenOptions::new()
.create(true)
.append(true)
.open("test.txt")
.unwrap();
let writer = BufWriter::with_capacity(100, file);
println!("{:#?}", writer.capacity()) // 100
}get_ref
获取对底层 writer 的引用。
pub fn get_ref(&self) -> &W返回值:返回内部writer的借用,例如:File、Vec<u8>、TcpStream
use std::fs::File;
use std::io::{BufWriter, Write};
fn main() {
let file = File::create("test.txt").unwrap();
let mut writer = BufWriter::new(file);
// ✅ 查看文件信息(不拿走)
let meta = writer.get_ref().metadata().unwrap();
println!("file size: {:#?}", meta);
// writer仍然可以继续写
writer.write_all(b"hello").unwrap();
}get_mut
获取底层 writer 的可变引用。
直接写给底层的 writer 是不可取的。
pub fn get_mut(&mut self) -> &mut W返回值:返回内部writer的可变借用,例如:File、Vec<u8>、TcpStream
use std::fs::File;
use std::io::{BufWriter, Write};
fn main() {
let mut file = File::create("test.txt").unwrap();
let mut writer = BufWriter::new(file);
writer.write_all(b"hello").unwrap();
// ✅ 直接操作 File
writer.get_mut().set_len(0).unwrap();
writer.write_all(b"world").unwrap();
writer.flush().unwrap();
}buffer
返回对内部缓冲数据的引用。
- 只读
- 不消耗
- 不 flush
pub fn buffer(&self) -> &[u8]返回值:返回还没写进目标的内存缓冲区(只读)
use std::fs::File;
use std::io::{BufWriter, Write};
fn main() {
let file = File::create("out.txt").unwrap();
let mut writer = BufWriter::new(file);
writer.write_all(b"hello").unwrap();
// ✅ 数据还在内存里
println!("{:?}", writer.buffer()); // [104, 101, 108, 108, 111]
writer.flush().unwrap();
// ✅ flush 后为空
println!("{:?}", writer.buffer()); // []
}capacity
获取这个缓冲区的容量
pub fn capacity(&self) -> usize返回值:返回缓冲区的容量,单位字节
use std::fs::File;
use std::io::BufWriter;
fn main() {
let file = File::create("test.txt").unwrap();
let writer = BufWriter::new(file);
println!("默认容量{}", writer.capacity()); // 默认容量8192
let writer = BufWriter::with_capacity(200, writer.get_ref());
println!("指定容量{}", writer.capacity()); // 默认容量200
}into_inner
解包此 BufWriter<W>,返回底层 writer。
在返回 writer 之前将缓冲区写出。
- 自动 flush
- 返回原始写目标
BufWriter不能再用了
pub fn into_inner(self) -> Result<W, IntoInnerError<BufWriter<W>>>返回值:BufWriter<W>→W。返回底层的writer,包含在Result中,
use std::fs::File;
use std::io::{BufWriter, Write};
fn main() {
let file = File::create("out.txt").unwrap();
let mut writer = BufWriter::new(file);
writer.write_all(b"hello").unwrap();
// ✅ 结束缓冲,拿回 File
let file = writer.into_inner().unwrap();
println!("file: {:?}", file);
}TIP
✅ 写文件结束
✅ 返回 File给调用方
✅ 关闭前确保数据写完
into_parts
反汇编这个 BufWriter<W>,返回底层 writer,以及任何缓冲但未写入的数据。
把 BufWriter拆成“裸缓冲区 + 写目标”
- 不flush
- 不写磁盘
- 把“还没写的数据”直接给你
pub fn into_parts(self) -> (W, Result<Vec<u8>, WriterPanicked>)返回值:
use std::fs::File;
use std::io::{BufWriter, Write};
fn main() {
let file = File::create("test.txt").unwrap();
let mut writer = BufWriter::new(file);
writer.write_all(b"hello").unwrap(); // 写到 内存缓冲区
let (buf, file) = writer.into_parts();
println!("pending data: {:?}", buf); // [104, 101, 108, 108, 111]
println!("file: {:?}", file);
}Trait Implementations
impl<W> Debug for BufWriter<W>
impl<W> Debug for BufWriter<W>
where
W: Debug + Write,fmt
使用给定的格式化程序格式化该值。
fn fmt(&self, fmt: &mut Formatter<'_>) -> Resultimpl<W: Write> Drop for BufWriter<W>
drop
执行此类型的析构函数。
fn drop(&mut self)impl<W: Write + Seek> Seek for BufWriter<W>
seek
寻找底层 writer 中的偏移量(以字节为单位)。
寻找总是在寻找之前写出内部缓冲区。
fn seek(&mut self, pos: SeekFrom) -> Result<u64>rewind
返回到流的开头。
fn rewind(&mut self) -> Result<()>stream_len
返回此流的长度 (以字节为单位)。
fn stream_len(&mut self) -> Result<u64>stream_position
从流的开头返回当前查找位置。
fn stream_position(&mut self) -> Result<u64>impl<W: Write> Write for BufWriter<W>
write
在此 writer 中写入一个缓冲区,返回写入的字节数。
fn write(&mut self, buf: &[u8]) -> Result<usize>write_all
尝试将整个缓冲区写入此 writer。
fn write_all(&mut self, buf: &[u8]) -> Result<()>write_vectored
类似于 write,不同之处在于它是从缓冲区切片中写入数据的。
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize>is_write_vectored
确定此 Writer 是否具有有效的 write_vectored 实现。
fn is_write_vectored(&self) -> boolflush
刷新此输出流,确保所有中间缓冲的内容均到达其目的地。
fn flush(&mut self) -> Result<()>write_all_vectored
尝试将多个缓冲区写入此 writer。
fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> Result<()>write_fmt
将格式化的字符串写入此 writer,返回遇到的任何错误。
fn write_fmt(&mut self, fmt: Arguments<'_>) -> Result<()>by_ref
为这个 Write 实例创建一个 “by reference” 适配器。
fn by_ref(&mut self) -> &mut Self
where
Self: Sized,Auto Trait Implementations
impl<W> RefUnwindSafe for BufWriter<W>
impl<W> RefUnwindSafe for BufWriter<W>
where
W: RefUnwindSafe,impl<W> Send for BufWriter<W>
impl<W> Send for BufWriter<W>
where
W: Send,impl<W> Sync for BufWriter<W>
impl<W> Sync for BufWriter<W>
where
W: Sync,impl<W> Unpin for BufWriter<W>
impl<W> Unpin for BufWriter<W>
where
W: Unpin,impl<W> UnwindSafe for BufWriter<W>
impl<W> UnwindSafe for BufWriter<W>
where
W: UnwindSafe,Blanket Implementations
impl<T> Any for T
impl<T> Any for T
where
T: 'static + ?Sized,impl<T> Borrow<T> for T
impl<T> Borrow<T> for T
where
T: ?Sized,impl<T> BorrowMut<T> for T
impl<T> BorrowMut<T> for T
where
T: ?Sized,impl<T> From<T> for T
impl<T, U> Into<U> for T
impl<T, U> Into<U> for T
where
U: From<T>,impl<T, U> TryFrom<U> for T
impl<T, U> TryFrom<U> for T
where
U: Into<T>,impl<T, U> TryInto<U> for T
impl<T, U> TryInto<U> for T
where
U: TryFrom<T>,