使用 read_until() 时如何阻止 BufReader 在 Rust 中读取?

How can I stop a BufReader from reading in Rust when using read_until()?

我正在尝试使用 BufReader 加载一堆数据,然后使用 read_until() 扫描数据。但是,当 read_until() 到达 EOF 并且我的代码再次返回到数据的开头时,我很难辨别,创建了一个无限循环。当 read_until() 到达 EOF 时,我需要停止阅读。我如何在 Rust 中完成此操作?

这是我目前拥有的:

use std::fs::File;
use std::io::BufRead;
use std::io::BufReader;
use std::str;

fn main() -> std::io::Result<()> {
    let f1 = File::open("foo.txt")?;
    let mut reader = BufReader::new(f1);
    let mut byte_vec: Vec<u8> = Vec::new();
    loop {
        let my_bytes = reader.read_until(b'\n', &mut byte_vec);
        let is_valid_utf8 = str::from_utf8(&byte_vec);

        match is_valid_utf8 {
            Ok(the_str) => println!("{} is a valid UTF-8 String", the_str),
            Err(err) => println!("Error: {}", err),
        }
    }
    Ok(())
}

foo.txt 只有几行示例文本。代码将永远循环回到文件的开头。

检查编译器给你的警告,这就是它们在那里的原因!

warning: unreachable expression
  --> src/lib.rs:16:5
   |
16 |     Ok(())
   |     ^^^^^^
   |
   = note: #[warn(unreachable_code)] on by default

warning: unused variable: `my_bytes`
 --> src/lib.rs:8:13
  |
8 |         let my_bytes = reader.read_until(b'\n', &mut byte_vec);
  |             ^^^^^^^^ help: consider using `_my_bytes` instead
  |
  = note: #[warn(unused_variables)] on by default

编译器告诉你

  1. 你的循环永远不会退出——这就是你的无限循环。
  2. 您没有使用 read_until 的 return 值。

这两件事是相关的。检查 read_until 的文档,强调我的:

Read all bytes into buf until the delimiter byte or EOF is reached.

[...]

If successful, this function will return the total number of bytes read.

使用值:

let my_bytes = reader.read_until(b'\n', &mut byte_vec)?;
if my_bytes == 0 { break };

继续阅读文档,强调我的:

all bytes up to, and including, the delimiter (if found) will be appended to buf

您的 byte_vec 将继续累积之前的每一行。这就是为什么您认为 BufReader 是 returning 到输入的开头。您可能希望在每次循环迭代结束时clear它。

另请参阅:

  • How to check for EOF with `read_line()`?