【问题标题】:How can I write all of stdin to stdout without using lots of memory?如何在不使用大量内存的情况下将所有标准输入写入标准输出?
【发布时间】:2020-08-06 21:25:01
【问题描述】:

我想编写一个 Rust 程序,它将 stdin 中的所有内容复制到 stdout。到目前为止我有这个

fn main() {
    let mut stdin: io::Stdin = io::stdin();    
    let mut stdout: io::Stdout = io::stdout();

    let mut buffer: [u8; 1_000_000] = [0; 1_000_000];
    let mut n_bytes_read: usize = 0;
    let mut uninitialized: bool = true;
    while uninitialized || n_bytes_read > 0
    {
        n_bytes_read = stdin.read(&mut buffer).expect("Could not read from STDIN.");
        uninitialized = false;
    }
}

我将所有内容复制到大小为 100 万的缓冲区中,以免在有人向我的程序提供 3 GB 文件时炸毁内存。所以现在我想将它复制到标准输出,但我能找到的唯一原始写操作是stdout.write(&mut buffer) - 但这会写入整个缓冲区!我需要一种方法来写入特定数量的字节,例如stdout.write_only(&mut buffer, n_bytes_read)

我想以尽可能最基本的方式做到这一点,只需要最少的标准库导入。

【问题讨论】:

    标签: rust


    【解决方案1】:

    如果您只想在不占用太多内存的情况下从标准输入复制到标准输出,只需使用std::io::copy。它将数据从读取器流式传输到写入器。

    如果您的目标是写入缓冲区的一部分,则取出该缓冲区的一部分并将其传递给write

    stdout.write(&buffer[0..n_bytes_read]);
    

    切片不会复制数据,因此您不会使用更多内存。

    但请注意,write 可能不会写出您所要求的所有内容 - 它会返回实际写入的字节数。如果您使用write_all,它将写入整个切片。

    【讨论】:

    • Nitpick:范围左侧的0 是可选的:您也可以写&buffer[..n_bytes_read]
    • 哇,这就像魔术一样。即使切片本身的大小在编译时无法知道,指针可以是合法的,并且它仍然携带缓冲区的(动态)长度,以便write() 知道如何处理它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-08
    • 1970-01-01
    • 1970-01-01
    • 2018-12-06
    • 2014-07-03
    相关资源
    最近更新 更多