3

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:

2 Answers 2

4

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).

Sign up to request clarification or add additional context in comments.

Comments

3

Rust API documentation states that:

Note that end-of-file is considered an error, and can be inspected for in the error's kind field.

The IoError struct looks like this:

pub struct IoError {
    pub kind: IoErrorKind,
    pub desc: &'static str,
    pub detail: Option<String>,
}

The list is all kinds is at http://doc.rust-lang.org/std/io/enum.IoErrorKind.html

You can match it like this:

match stdio::stdin().read(buffer) {
    Ok(_) => println!("ok"),
    Err(io::IoError{kind:io::EndOfFile, ..}) => println!("end of file"),
    _ => println!("error")
}

1 Comment

Another way to check for EOF would be Err(ref e) if e.kind == io::EndOfFile which is arguably cleaner (less nesting)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.