读取字节时填充用户提供的缓冲区的惯用方法是什么?
What is an idiomatic way to fill a user-supplied buffer when reading bytes?
Read::read
returns 它实际读取的字节数,可以小于请求的缓冲区。在许多情况下,多次调用 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() {}
标准库中是否有一个函数可以为我抽象出这项工作?
This answer applies to versions of Rust before 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,它是几个月前提交的,进入了最后的评论期,然后进行了足够的更改,以至于它被 out 的最后评论期和正在等待另一次复飞。
原来这出乎意料的复杂。 :P
由于 RFC mentioned in the other answer is accepted, implemented, and available in Rust 1.6.0, you can just use the Reader::read_exact()
方法:
try!(r.read_exact(&mut buf))
或者,使用 ?
运算符 introduced in Rust 1.13.0:
r.read_exact(&mut buf)?
Read::read
returns 它实际读取的字节数,可以小于请求的缓冲区。在许多情况下,多次调用 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() {}
标准库中是否有一个函数可以为我抽象出这项工作?
This answer applies to versions of Rust before 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,它是几个月前提交的,进入了最后的评论期,然后进行了足够的更改,以至于它被 out 的最后评论期和正在等待另一次复飞。
原来这出乎意料的复杂。 :P
由于 RFC mentioned in the other answer is accepted, implemented, and available in Rust 1.6.0, you can just use the Reader::read_exact()
方法:
try!(r.read_exact(&mut buf))
或者,使用 ?
运算符 introduced in Rust 1.13.0:
r.read_exact(&mut buf)?