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());
}

但是Read::chars从 Rust v1.6.0 开始仍然不稳定。

我考虑过使用 Read::read_to_string ,但文件可能很大,我不想将其全部读入内存。

最佳答案

让我们比较 4 种方法。

<强>1。 读取::字符

你可以复制Read::chars实现,但它被标记为不稳定

the semantics of a partial read/write of where errors happen is currently unclear and may change

所以一定要小心。无论如何,这似乎是最好的方法。

<强>2。 flat_map

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 借用了字符串,但是 l.expect("lines failed") 只存在于闭包中,所以编译器给出了错误 借来的值(value)活得不够长

<强>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);
        }
    }
}

有效,但它会为每一行分配一个字符串。此外,如果输入文件没有换行符,整个文件将被加载到内存中。

<强>4。 BufRead::read_until

方法 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();
    }
}

关于io - 在 Rust 中逐个字符地读取文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35385703/

相关文章:

c - 重定向标准输出,不理解行为

java - 我的文件输出被复制。每个新的 println 都包含之前的所有内容。 (包含代码)

c - 带有管道的简单主函数中的错误文件号

build - 使用 Cargo 进行源代码构建(外部构建目录)?

java - 通过 USB 从 Java 程序读取时,Arduino 出现 Serial.readbytes() 问题

java - 如何停止等待 System.in 的线路?

rust - 从 HashMap 或 Vec 返回引用会导致借用超出其所在范围?

rust - 根据条件如何将输出分配给变量匹配类型

rust - 已弃用的别名不会生成警告

rust - Actix-Web 在处理文件上传时报告 "App data is not configured"