2

我有一个非常大的文件,“应该”由 JSON 字符串组成。但是,当我使用以下代码时,我得到一个“流不包含有效的 UTF8”。

let file = File::open("foo.txt")?;
let reader = BufReader::new(file);

for line in reader.lines() {
    println!("{}", line?);
}

Ok(())

现在的答案是使用 Vec 而不是 String。但是我看到的所有代码都file.read_to_end(buf)作为答案,不适用于我必须使用的文件大小。

我正在寻找的是逐行读取文件,使用有损 utf8 转换,然后进行一些计算并将输出推送到另一个文件。

4

1 回答 1

3

您可以使用 BufReader 的read_until功能。它与 File 非常相似read_to_end,但也带有byte分隔符参数。此分隔符可以是任何字节,换行\n字节适合您。之后,您可以从 UTF-8 有损地转换缓冲区。它看起来像这样:

let file = File::open("foo.txt")?;
let mut reader = BufReader::new(file);
let mut buf = vec![];

while let Ok(_) = reader.read_until(b'\n', &mut buf) {
    if buf.is_empty() {
        break;
    }
    let line = String::from_utf8_lossy(&buf);
    println!("{}", line);
    buf.clear();
}

Ok(())

当然,这可以抽象成一个迭代器,就像Lines做的那样,但基本逻辑和上面一样。

注意:与lines函数不同,生成的字符串将包括换行符和回车符 ( \r)(如果有的话)。lines如果解决方案的行为必须与函数匹配,则需要去除这些字符。

于 2020-07-03T20:37:32.780 回答