gpt4 book ai didi

rust - 直接从文件读取到 BufReader 或 Cursor 的底层缓冲区

转载 作者:行者123 更新时间:2023-11-29 08:14:50 24 4
gpt4 key购买 nike

我正在尝试了解 Rust 中的一些基本内容。

我想创建一个工具,从一个文件中读取 512 个字节,并将这些字节复制到另一个文件中。然后从输入文件中取出接下来的 8 个字节并跳过它们。然后从输入文件中取出接下来的 512 个字节,并将它们复制到输出文件,然后跳过 8 个字节,等等...

我需要这个工具的速度,所以我不能每 512 字节执行一次 I/O 调用。我想我需要先读取几兆字节的输入文件,然后通过有选择地将其复制到另一个内存块来删除内存中不需要的 8 字节 block ,然后调用 I/O write 将更大的内存块转储到一次。

所以,我想做这样的事情(伪代码):

let buffer = buffer of 'u8' of size 4MB;
let buffer_out = buffer of 'u8' of size 4MB;

// both buffers above take 8MB of memory

let input_stream = InputStream(buffer);
let output_stream = OutputStream(buffer_out);

for(every 4MB block in the input file) {
input.read(buffer); // read the 4MB block into 'buffer'
input_stream.seek(0); // reset the input stream's cursor to offset 0

for(every 520 byte inside the 4MB block in 'buffer') {
output_stream.write(input_stream.read(512)); // copy important 512 bytes
input_stream.read(8); // skip superfluous 8 bytes
}

output.write(buffer_out);
}

我在 Rust 中遇到的问题是我正在尝试使用 Cursor对象来实现对两个缓冲区的流式访问。例如,我像这样在堆上分配缓冲区:

let mut buf: Box<[u8; BUF_SIZE]> = Box::new([0; BUF_SIZE]);

然后我创建了一个 Cursor 来以流模式访问这个数组:

let mut rd_cursor: Cursor<&[u8]> = Cursor::new(buf.as_slice());

但是,我现在不知道如何从输入文件中读取数据。 bufCursor 使用,所以我无法访问它。在 C++ 中,我只会将数据读取到 buf并完成它。和 Cursor似乎没有实现任何可以被 BufReader.read() 直接使用的东西,我用它从输入文件中读取数据。

也许我可以通过创建另一个缓冲区来使其工作,将数据从“input”读取到临时缓冲区,通过游标从临时缓冲区读取到“buf”,但这会导致不断地重新复制内存,我希望如此避免。

我可以看到有一个 fill_bufCursor 中发挥作用,但它似乎只返回对底层缓冲区的只读引用,所以我无法修改缓冲区,因此它对我的情况毫无用处。

我也尝试过使用 BufReader而不是 Cursor .这是我的第二次尝试:

let mut rd_cursor: BufReader<&[u8]> = BufReader::new(&*buf);

BufReader<R>包含 get_mut返回 R ,所以我认为它应该返回 &[u8]就我而言,这听起来是件好事。但是通过使用 &[u8] , get_mut提示我需要传递一个可变的东西作为 R .所以我正在改变它:

let mut rd_cursor: BufReader<&mut [u8]> = BufReader::new(&mut *buf);

但是 Rust 不允许我:

src\main.rs|88 col 47| 88:61 error: the trait `std::io::Read` is not implemented for the type `[u8]` [E0277]
|| src\main.rs:88 let mut rd_cursor: BufReader<&mut [u8]> = BufReader::new(&mut *buf);

谁能打我的脑袋来修正我对这里发生的事情的理解?

最佳答案

BufReader 已经缓冲读取。引用文档:

Wraps a Read and buffers input from it

It can be excessively inefficient to work directly with a Read instance. For example, every call to read on TcpStream results in a system call. A BufReader performs large, infrequent reads on the underlying Read and maintains an in-memory buffer of the results.

您可以简单地将容量设置为几兆字节,然后在您的 512 + 8 字节读取周期上工作。 BufReader 只会在您用完缓冲区时执行实际的系统调用。


下面的错误

error: the trait std::io::Read is not implemented for the type [u8] [E0277]

是因为 rust 不知道你想要多少字节。 [u8] 是一个未调整大小的数组。我不确定你是否可以执行 &mut [u8, BUF_SIZE] 但你需要一些类似的东西

关于rust - 直接从文件读取到 BufReader 或 Cursor 的底层缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28623802/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com