Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading Bytes From a Reader

Tags:

rust

I'm writing something to process stdin in blocks of bytes, but can't seem to work out a simple way to do it (though I suspect there is one).

fn run() -> int {
    // Doesn't compile: types differ
    let mut buffer = [0, ..100];
    loop {
        let block = match stdio::stdin().read(buffer) {
            Ok(bytes_read) => buffer.slice_to(bytes_read),
            // This captures the Err from the end of the file,
            // but also actual errors while reading from stdin.
            Err(message) => return 0
        };
        process(block).unwrap();
    }
}

fn process(block: &[u8]) -> Result<(), IoError> {
  // do things
}

My questions:

  • What's the "standard" way to do this? (I've been trying/hoping to use and_then()/or_else())
  • How can I differentiate between the Err(IoError) from end of the file, and the Err that's actually an error?
like image 590
Daniel Avatar asked Aug 18 '26 23:08

Daniel


1 Answers

The previously accepted answer was outdated (Rust v1.0). EOF is no longer considered an error. You can do it like this:

use std::io::{self, Read};

fn main() {
    let mut buffer = [0; 100];
    while let Ok(bytes_read) = io::stdin().read(&mut buffer) {
        if bytes_read == 0 { break; }
        process(&buffer[..bytes_read]).unwrap();
    }
}

fn process(block: &[u8]) -> Result<(), io::Error> {
    Ok(()) // do things
}

Note that this may not result in the expected behavior: read doesn't have to fill the buffer, but may return with any number of bytes read. In the case of stdin the read implementation returns every time a newline is detected (pressing enter in terminal).

like image 165
Lukas Kalbertodt Avatar answered Aug 22 '26 05:08

Lukas Kalbertodt



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!