什么是在读取字节时填充用户提供的缓冲区的惯用方式?

问题描述:

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

不受限制,只要我知道了。

望着byteordercrate'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