逐行读取大文件并避免 Rust 中的 utf8 错误
Reading a large file line by line and avoiding utf8 errors in Rust
我有一个非常大的文件,“应该”包含 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 转换,然后进行一些计算并将输出推送到另一个文件。
您可以使用 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
函数不同,生成的字符串将包含换行符和回车符 return (\r
)(如果有的话)。如果解决方案的行为必须与 lines
函数匹配,则需要去除这些字符。
我有一个非常大的文件,“应该”包含 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 转换,然后进行一些计算并将输出推送到另一个文件。
您可以使用 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
函数不同,生成的字符串将包含换行符和回车符 return (\r
)(如果有的话)。如果解决方案的行为必须与 lines
函数匹配,则需要去除这些字符。