2015-07-12 10 views
7

Read::read restituisce il numero di byte effettivamente letti, che può essere inferiore al buffer richiesto. In molti casi, è possibile effettuare più chiamate allo read per riempire completamente il buffer.Qual è un modo idiomatico per riempire un buffer fornito dall'utente durante la lettura dei byte?

Ho questo codice, ma sembra piuttosto sgraziato:

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() {} 

C'è una funzione della libreria standard che sarà estratto questo lavoro per me via?

risposta

3

Dal momento che la RFC di cui l'altra risposta è stata accettata, implementato, e disponibili a Rust 1.6.0, si può semplicemente utilizzare il metodo Reader::read_exact():

try!(r.read_exact(&mut buf)) 

Oppure, utilizzando l'operatore di ?introduced in Rust 1.13.0:

r.read_exact(&mut buf)? 
4

Questa risposta si applica alle versioni di Rust prima 1.6.0

Non per quanto ne so.

Guardando il byteordercrate's source, c'è un metodo read_all definito anche lì:

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(()) 
} 

Si noti che questo si occupa di operazioni di IO interrotti.

C'è anche un proposed RFC, che è stata presentata alcuni mesi fa, è andato al periodo di commento finale, poi cambiato abbastanza che è stato preso fuori del periodo di commento finale ed è in attesa per un altro go-around.

Si scopre che questo è inaspettatamente complicato. : P

Problemi correlati