Io 在Rust中逐字读取文件
是否有一种惯用的方法在Rust中一次处理一个字符的文件 这大概就是我想要的:Io 在Rust中逐字读取文件,io,rust,Io,Rust,是否有一种惯用的方法在Rust中一次处理一个字符的文件 这大概就是我想要的: let mut f = io::BufReader::new(try!(fs::File::open("input.txt"))); for c in f.chars() { println!("Character: {}", c.unwrap()); } 但在Rust v1.6.0中仍然不稳定 我考虑过使用,但文件可能很大,我不想将其全部读入内存。这里有两种解决方案 首先,您可以复制Read::chars
let mut f = io::BufReader::new(try!(fs::File::open("input.txt")));
for c in f.chars() {
println!("Character: {}", c.unwrap());
}
但在Rust v1.6.0中仍然不稳定
我考虑过使用,但文件可能很大,我不想将其全部读入内存。这里有两种解决方案 首先,您可以复制
Read::chars()
的实现并使用它;如果代码稳定下来,那么将代码移到标准库实现中就变得非常简单了
另一方面,您可以简单地逐行迭代(使用f.lines()
),然后在每一行上使用line.chars()
)来获取字符。这是一个有点黑客,但它肯定会工作
如果您只需要一个循环,那么可以将
flat_map()
与类似于|line | line.chars()的lambda一起使用
1<代码>读取::字符
您可以复制实现,但它被标记为不稳定
错误发生位置的部分读/写的语义目前尚不清楚,可能会发生变化
因此,必须小心一些。无论如何,这似乎是最好的办法
2<代码>平面地图
平面图
备选方案未编译:
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
从字符串中借用,但l.expect(“行失败”)
仅在闭包中存在,因此编译器给出的错误借用值的存在时间不够长
3。嵌套用于
此代码
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);
}
}
}
工作正常,但它为每行保留一个字符串。此外,如果输入文件上没有换行符,则整个文件将加载到内存中
4BufRead::一直读到
方法3的一个内存有效的替代方法是使用Read::Read_直到,并使用单个字符串读取每一行:
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();
}
}
使用std::io::{BufRead,BufReader};
使用std::fs::File;
pub fn main(){
让mut f=BufReader::new(File::open(“input.txt”).expect(“open failed”);
让mut buf=Vec:::new();
而f.read_until(b'\n',&mut buf).expect(“read_until failed”)!=0{
//这会将读取数据的所有权移动到s
//没有分配
让s=String::from_utf8(buf).expect(“from_utf8失败”);
对于s.chars()中的c{
println!(“字符:{}”,c);
}
//这会将读取数据的所有权返回给buf
//没有分配
buf=s.到_字节();
buf.clear();
}
}
我不能使用行()
,因为我的文件可能是一行大小为千兆字节的文件。这是从旧版本的Rust复制Read::chars
的改进。已为您将.chars()
添加到BufRead
检查它们的内存,看起来它们一次加载的字节不会超过4个
您的代码看起来将与除锈前相同Read::chars
:
use std::io::stdin;
use utf8_chars::BufReadCharsExt;
fn main() {
for c in stdin().lock().chars().map(|x| x.unwrap()) {
println!("{}", c);
}
}
将以下内容添加到Cargo.toml中:
[dependencies]
utf8-chars = "1.0.0"
对于某些类型的文本文件:f.lines().flat_map(|l | l.chars())
。。。但这并不是一个好的解决方案。您是否考虑过同时复制实现?它只有约100行,这意味着如果chars
保持原样,您的代码将很容易升级。作为提醒,通常可以将有用的注释移动到答案中,但如果您不是真的添加到内容中,则可能是。抱歉!我下次一定要这么做。我在哪里可以找到旧的Read::chars()实现?现在我已经决定使用这个板条箱: