如何编写大于2GB的文件?

3
以下代码:
use std::fs::File;
use std::io::Write;

fn main() {
    let encoded: Vec<u8> = vec![0; 2500000000];
    let mut buffer = File::create("file.bin").unwrap();
    let written_bytes = buffer.write(&encoded).unwrap();
    assert_eq!(written_bytes, encoded.len());
}

错误提示:

thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `2147479552`,
 right: `2500000000`', src/main.rs:8:5

似乎有一个2^31 - 4096字节的限制。

我该如何解决这个问题?我想写一个更大的文件。 :)


此外,创建一个2.5 GB的向量是不合理的。请使用较小的缓冲区。2^8到2^16之间的大小更为合适。 - Stargateur
1个回答

6
Rust的write依赖于底层操作系统来写入字节。
对于Linux系统,将使用write系统调用
根据POSIX.1的规定,如果count大于SSIZE_MAX,则结果是实现定义的;在Linux上,请参阅有关上限的NOTES。
注:
在Linux上,write()(和类似的系统调用)最多传输0x7ffff000(2,147,479,552)个字节,返回实际传输的字节数。(这适用于32位和64位系统。)
因此,这就是所谓的魔法数字产生的原因。
为了避免问题,应该使用write_all而不是write,它将确保写入所有字节。
请注意:如果在Windows下运行程序,则可以正常运行。

谢谢。这样更好。毕竟不需要 BufWriter。 :) - Tobias Hermann
出于性能考虑,BufWriter 仍然更可取。可以尝试对两者进行基准测试。 - Matthieu M.
我认为,具体的posix并不重要,只需要rust的文档就足够了。"将缓冲区写入此对象,并返回写入的字节数。",https://doc.rust-lang.org/nightly/std/io/trait.Write.html#tymethod.write - Stargateur
@Stargateur 你是对的,但manpage解释了为什么只写了2147479552个字节。 - hellow

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接