簡體   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