繁体   English   中英

如何读取文件的大部分而不用尽 Rust 中的 memory?

[英]How to read large portions of a file without exhausting memory in Rust?

我正在尝试重写 GNU coreutils 'split' 工具的一部分,以将文件拆分为大小大致相同的多个部分。

我的程序的一部分正在读取文件的大部分内容,只是为了将它们写入另一个文件。 在 memory 方面,我不想 map memory 中的这些部分,因为它们的长度可以从零字节到几千兆字节不等。

这是我使用 BufReader 编写的代码的摘录:

let file = File::open("myfile.txt");
let mut buffer = Vec::new();
let mut reader = BufReader::new(&file); 
let mut handle = reader.take(length);  // here length can be 10 or 1Go !
let read = handle.read_to_end(&mut buffer);

由于read_to_end(&mut buffer)调用,我觉得我正在映射 memory 中的整个文件块。 我是吗? 如果不是,这是否意味着 BufReader 正在完成它的工作,我是否可以承认它正在做某种魔术(抽象),允许我“读取”文件的整个部分,而无需真正将其映射到 memory? 还是我在代码中滥用了这些概念?

是的,您正在将整个块读入 memory。 您可以检查buffer以确认。 如果它有length字节,那么你就是 go; memory 中有length字节。 BufReader无法伪造这一点。

是的,如果我们查看read_to_end function 的来源,我们可以看到,如果向量中的可用空间用尽,您提供的缓冲区将被扩展以保存新数据。

甚至只是在文档中,rust 告诉我们在EOF进入缓冲区之前读取所有内容:

读取此源中直到 EOF 的所有字节,将它们放入 buf

您还可以使用BufReader查看此问题中提供的代码作为起点:

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

更好的方法可能是设置一个无缓冲的Reader ,并将字节直接读取到缓冲区中,同时检查您是否没有超出用户指定的任何字节或行边界,并将缓冲区内容写入文件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM