Как я могу остановить чтение BufReader в Rust при использовании 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 есть несколько строк примера текста. Код будет зацикливаться обратно к началу файла.

1 ответ

Решение

Проверьте предупреждения, которые дает вам компилятор, вот почему они есть!

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,

Эти две вещи связаны между собой. Проверьте документы для read_until Акцент мой:

Считайте все байты в buf, пока не будет достигнут байт разделителя или EOF.

[...]

В случае успеха эта функция вернет общее количество прочитанных байтов.

Используйте значение:

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

Продолжите читать документы, акцент мой:

все байты до, включая разделитель (если найден), будут добавлены к buf

Ваш byte_vec будет продолжать накапливать каждую предыдущую строку. Вот почему вы считаете, что BufReader возвращается к началу ввода. Вы, вероятно, хотите clear это в конце каждой итерации цикла.

Смотрите также:

Другие вопросы по тегам