以块的形式读取大文件的最有效方法

Jac*_*own 11 io file rust

阅读"大"文件(可能是文本或二进制文件)而不进入unsafe领域的最有效的通用方法是什么?当我在网上搜索"大块读取大块文件"时,我感到很惊讶.

例如,我的一个用例是使用rust-crypto(该Md5模块允许您&[u8]迭代地添加块)来计算文件的MD5校验和.

这就是我所拥有的,它似乎比其他一些方法表现得稍好一些read_to_end:

use std::{
    fs::File,
    io::{self, BufRead, BufReader},
};

fn main() -> io::Result<()> {
    const CAP: usize = 1024 * 128;
    let file = File::open("my.file")?;
    let mut reader = BufReader::with_capacity(CAP, file);

    loop {
        let length = {
            let buffer = reader.fill_buf()?;
            // do stuff with buffer here
            buffer.len()
        };
        if length == 0 {
            break;
        }
        reader.consume(length);
    }

    Ok(())
}
Run Code Online (Sandbox Code Playgroud)

Eli*_*man 7

我不认为你可以编写比这更高效的代码. fill_buf在一个BufReader超过a File基本上只是一个直接的电话read(2).见https://github.com/rust-lang/rust/blob/e1195c24bb567019d7cdc65bf5a4c642e38475d1/src/libstd/io/buffered.rs#L185.

也就是说,当你像这样使用时,BufReader并不是真正有用的抽象; BufReader直接打电话可能不那么尴尬.

  • *因为它调整了缓冲区的大小* - 我怀疑它调整了缓冲区的大小,但是可能缩短了切片以反映读取的字节数.但你是对的,`Read :: read`的返回值告诉你有多少缓冲区是有效的.使用它是非常重要的**,否则你会遇到像Heartbleed这样的问题,其中缓冲区被重用旧内容!这可能是使用"BufReader"的一个很好的理由. (2认同)