读取文件时检测EndOfFile IoResult

读取文件时检测EndOfFile IoResult,io,rust,Io,Rust,我正试图从一个生锈的文件中读取数据。我不明白的是:当BufferedReader处于EOF时,它实际上给出了一个Err(IoError{kind:EndOfFile}),我不知道如何匹配它 loop { match file.read_line() { Ok(line) => { // Do stuff }, // Err(EndOfFile) => is want I want here so I can call "break" E

我正试图从一个生锈的文件中读取数据。我不明白的是:当
BufferedReader
处于EOF时,它实际上给出了一个
Err(IoError{kind:EndOfFile})
,我不知道如何匹配它

loop {
  match file.read_line() {
    Ok(line) => {
      // Do stuff
    },
    // Err(EndOfFile) => is want I want here so I can call "break"
    Err(_) => {
      panic!("Unexpected error reading file.");
    }
  }
}

如何显式匹配
EndOfFile
enum变量?

专门用于迭代行,rust具有用于缓冲区()的
函数

在您的情况下,您将在线路上循环,一旦达到EOF,循环将自动中止,无需您的干预

for line in file.lines() {
    match line {
        Ok(line) => {
            // do stuff
        },
        Err(_) => {
            println!("Unexpected error reading file.")
        }
    }
}
或者,如果函数返回兼容的
结果
,则可以使用try!减少噪音的宏:

fn myfun(file: File) -> IoResult<()> {
    for line in file.lines() {
        let line = try!(line);
        // do stuff
    }
}
fn myfun(文件:file)->IoResult{
对于文件中的行。行(){
让线=尝试!(线);
//做事
}
}
如何显式匹配EndOfFile枚举变量

您可以使用以下模式匹配它,而无需其他嵌套匹配:

loop {
  match file.read_line() {
    Ok(line) => {
      // Do stuff
    },
    Err(IoError { kind: EndOfFile, .. }) =>
      break,
    Err(_) => {
      panic!("Unexpected error reading file.");
    }
  }
}

看起来rust post 1.0已将
IoError
更改为
std::io::Error
。另外,
kind
现在隐藏在内部。我必须使用a来处理类似类型的问题(
WouldBlock
,而不是
endofile

e、 g


对于在现代版本的rust post 1.0上阅读此内容的任何人,现在规定,在尝试读取文件时到达文件末尾肯定不是错误,应该用
Ok(0)
(与其他编程语言/框架非常相似)表示,而不是硬错误

由于您可以直接匹配读取的字节数(与
std::io::error
不同,
ErrorKind
成员是隐藏的,无法直接匹配),因此处理起来非常简单:

        let mut buf: Vec<u8> = Vec::new();
        loop {
            let bytes_read = match file.read(&mut buf) {
                Ok(0) => break, // end-of-file
                Ok(n) => n,
                Err(e) => // handle error however you see fit,
            };
让mut buf:Vec=Vec::new();
环路{
让bytes_read=匹配file.read(&mut buf){
确定(0)=>中断,//文件结束
Ok(n)=>n,
Err(e)=>//以您认为合适的方式处理错误,
};

当模式匹配不足时,您可以始终使用:
Err(e)if e.kind==EndOfFile=>…
例如。但不确定这是否是最好的。@MatthieuM。我想避免这种情况。也许我可以采取另一种方法来改变我的控制流,但更容易
读取
直到EOF。我完全理解,但我不太清楚(我可能缺乏经验)这就是为什么它是一个注释而不是一个答案。这可能是你问题的答案。@ker的回答是你问题的解决方案。^ ^这就是
本身的实现方式。这确实是我问题的答案。因为它实际上是一个更好的流程,所以对@ker投了赞成票。另一种可能性是编写
>Err(e)如果e.kind==EndOfFile=>
,但模式匹配可能更好。这看起来比我的要好得多。我可能只是避免进行令人讨厌的结构模式匹配,感谢这一技巧。事实上,现在在
读取
时处于生锈的EOF状态是通过返回0(读取的字节数)发出信号的。
        let mut buf: Vec<u8> = Vec::new();
        loop {
            let bytes_read = match file.read(&mut buf) {
                Ok(0) => break, // end-of-file
                Ok(n) => n,
                Err(e) => // handle error however you see fit,
            };