File 在不同时将整个文件加载到内存中的情况下,以块形式读取大文件的最有效方法是什么?
在不进入File 在不同时将整个文件加载到内存中的情况下,以块形式读取大文件的最有效方法是什么?,file,io,rust,File,Io,Rust,在不进入不安全领域的情况下,读取“大”文件(可能是文本或二进制文件)的最有效的通用方法是什么?当我在网上搜索“分块读取大文件”时,我惊讶地发现相关结果竟然很少 例如,我的一个用例是使用rust crypto计算文件的MD5校验和(使用MD5模块可以迭代地添加和[u8]块) 以下是我所拥有的,它的性能似乎比其他一些方法稍好一些,比如read\u to\u end: use std::{ fs::File, io::{self, BufRead, BufReader}, }; fn
不安全领域的情况下,读取“大”文件(可能是文本或二进制文件)的最有效的通用方法是什么?当我在网上搜索“分块读取大文件”时,我惊讶地发现相关结果竟然很少
例如,我的一个用例是使用rust crypto
计算文件的MD5校验和(使用MD5
模块可以迭代地添加和[u8]
块)
以下是我所拥有的,它的性能似乎比其他一些方法稍好一些,比如read\u to\u 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(())
}
使用std::{
fs::文件,
io:{self,BufRead,BufReader},
};
fn main()->io::Result{
常数上限:usize=1024*128;
让file=file::open(“my.file”)?;
让mut reader=BufReader::具有_容量(CAP,file);
环路{
让长度={
让buffer=reader.fill_buf()?;
//在这里使用缓冲区
buffer.len()
};
如果长度==0{
打破
}
读者消费(长度);
}
好(())
}
我认为你写代码的效率再高不过了<代码>在BufReader
上填充文件
是
也就是说,BufReader
在这样使用它时并不是一个真正有用的抽象;直接调用file.read(&mut buf)
可能不会那么尴尬。谢谢您的回答!我认为,BufReader
对我很有用,因为当我到达读卡器的末尾时,它为我调整了缓冲区的大小,但我刚刚意识到这很简单…因为它调整了缓冲区的大小-我怀疑它是否调整了缓冲区的大小,但片可能会缩短以反映读取的字节数。但是您是对的,Read::Read
的返回值告诉您有多少缓冲区是有效的。使用它是非常重要的,否则您可能会遇到像Heartbleed这样的问题,缓冲区会被旧内容重用!这可能是使用BufReader
的一个很好的理由。对不起,你是对的,我的意思是“缩短了缓冲区的长度”。为什么要对fill\u buf进行闭包?我有一个问题,这个关闭修复。你能给我指一下正确的方向吗。@Townsheriff,你的意思是,为什么reader.fill_buf()?
在一个块中(let length={…}
)?如果是这样的话,那是因为2016年的借债检查程序没有现在那么复杂。如果我把fill_buf
和consume
放在同一个范围内,rustc会抱怨不能借用'reader',因为一次可以修改一次以上fill_buf
返回对底层阅读器的引用,因此将其放在一个较短的范围内可能是解决问题的方法。是的,这正是我在今天的稳定版本中遇到的问题。非常感谢,干杯!