什么是在读取字节时填充用户提供的缓冲区的惯用方式?
问题描述:
Read::read
返回实际读取的字节数,该字节数可能小于请求的缓冲区。在许多情况下,可以多次调用read
以完全填充缓冲区。什么是在读取字节时填充用户提供的缓冲区的惯用方式?
我有这样的代码,但它似乎很笨拙:
use std::io::{self, Read};
fn read_complete<R>(mut rdr: R, buf: &mut [u8]) -> io::Result<()>
where R: Read
{
let mut total_read = 0;
loop {
let window = &mut buf[total_read..];
let bytes_read = try!(rdr.read(window));
// Completely filled the buffer
if window.len() == bytes_read {
return Ok(());
}
// Unable to read anything
if bytes_read == 0 {
return Err(io::Error::new(io::ErrorKind::Other, "Unable to read complete buffer"));
}
// Partial read, continue
total_read += bytes_read;
}
}
fn main() {}
是否有一个函数在标准库,它抽象这项工作离开我吗?
答
由于对方的回答中提到的RFC被接受,实现和拉斯特1.6.0可用,您可以只使用Reader::read_exact()
方法:
try!(r.read_exact(&mut buf))
或者使用?
运营商introduced in Rust 1.13.0:
r.read_exact(&mut buf)?
答
这个答案适用于锈之前的版本1.6.0
不受限制,只要我知道了。
望着byteorder
crate's source,有定义有一个read_all
方法,太:
fn read_full<R: io::Read + ?Sized>(rdr: &mut R, buf: &mut [u8]) -> Result<()> {
let mut nread = 0usize;
while nread < buf.len() {
match rdr.read(&mut buf[nread..]) {
Ok(0) => return Err(Error::UnexpectedEOF),
Ok(n) => nread += n,
Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {},
Err(e) => return Err(From::from(e))
}
}
Ok(())
}
注意,这与中断的IO操作的交易。
还有一个proposed RFC,已提交数个月前,就到最后的评论期,然后改变了,以至于它被采取了最终意见征询期和正在等待另一个复飞。事实证明,这是意想不到的复杂。 :P