在编写二进制文件格式时,检查已写入多少字节很有用(例如进行对齐),或者只是为了确保嵌套函数写入了正确的数据量。
是否有一种方法可以检查 std::io::Write
已经写入了多少字节?如果没有,那么包装写入器以跟踪已写入多少字节会是一个好方法?
Write
具有两个必需的方法:write
和flush
。由于write
已经返回了已写入字节数,因此您只需要跟踪它:
use std::io::{self, Write};
struct ByteCounter<W> {
inner: W,
count: usize,
}
impl<W> ByteCounter<W>
where W: Write
{
fn new(inner: W) -> Self {
ByteCounter {
inner: inner,
count: 0,
}
}
fn into_inner(self) -> W {
self.inner
}
fn bytes_written(&self) -> usize {
self.count
}
}
impl<W> Write for ByteCounter<W>
where W: Write
{
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
let res = self.inner.write(buf);
if let Ok(size) = res {
self.count += size
}
res
}
fn flush(&mut self) -> io::Result<()> {
self.inner.flush()
}
}
fn main() {
let out = std::io::stdout();
let mut out = ByteCounter::new(out);
writeln!(&mut out, "Hello, world! {}", 42).unwrap();
println!("Wrote {} bytes", out.bytes_written());
}
不要委托write_all
或write_fmt
,因为它们不返回字节数量。委托它们会导致字节被写入但无法跟踪。
std::io::Seek
,则可以使用seek
获取当前位置:pos = f.seek(SeekFrom::Current(0))?;
Seek
是由std::fs::File
实现的(如果包装类型也实现了Seek
,则还有std::io::BufWriter
)。
因此,函数签名为:
use ::std::io::{Write, Seek, SeekFrom, Error};
fn my_write<W: Write>(f: &mut W) -> Result<(), Error> { ... }
需要添加Seek
特性:
fn my_write<W: Write + Seek>(f: &mut W) -> Result<(), Error> { ... }
Seek
不能被实现或者不可用,我也不介意你将这个标记为答案。 - wimh