让我们比较一下4种方法.
1. 100
您可以复制Read::chars
个实现,但它标记为不稳定
错误发生位置的部分读/写的语义目前尚不清楚,可能会发生变化
因此,必须小心一些.无论如何,这似乎是最好的方法.
2. 100
flat_map
个备选方案没有编译:
use std::io::{BufRead, BufReader};
use std::fs::File;
pub fn main() {
let mut f = BufReader::new(File::open("input.txt").expect("open failed"));
for c in f.lines().flat_map(|l| l.expect("lines failed").chars()) {
println!("Character: {}", c);
}
}
问题是chars
从字符串中borrow ,但l.expect("lines failed")
只存在于闭包中,所以编译器给出了错误borrowed value does not live long enough
.
3. Nested for
这个代码
use std::io::{BufRead, BufReader};
use std::fs::File;
pub fn main() {
let mut f = BufReader::new(File::open("input.txt").expect("open failed"));
for line in f.lines() {
for c in line.expect("lines failed").chars() {
println!("Character: {}", c);
}
}
}
行,但它为每行保留一个字符串.此外,如果输入文件上没有换行符,整个文件将被加载到内存中.
4. 100
方法3的另一种节省内存的方法是使用Read::read_until
,并使用单个字符串读取每一行:
use std::io::{BufRead, BufReader};
use std::fs::File;
pub fn main() {
let mut f = BufReader::new(File::open("input.txt").expect("open failed"));
let mut buf = Vec::<u8>::new();
while f.read_until(b'\n', &mut buf).expect("read_until failed") != 0 {
// this moves the ownership of the read data to s
// there is no allocation
let s = String::from_utf8(buf).expect("from_utf8 failed");
for c in s.chars() {
println!("Character: {}", c);
}
// this returns the ownership of the read data to buf
// there is no allocation
buf = s.into_bytes();
buf.clear();
}
}