我需要将文件分成N个字节的段。目前,我使用的代码将文件分成固定大小的段(LEN
)。然而,我需要使用计算值而不是LEN
。问题是let mut slice_buffer = [0u8; LEN];
只能使用LEN
的常量值,而我不能使用变量。
有没有一种替代方法可以将任意长度的向量块推送到file_slices: Vec<Vec<u8>>
,以便file_slices.len() < 255
不受文件大小的影响?
let mut file = match File::open(path).unwrap();
const LEN: usize = 4096;
let mut file_slices: Vec<Vec<u8>> = Vec::new();
let mut slice_buffer = [0u8; LEN];
let mut bytes_in_last_row = 0;
//slice the file into 4096 byte slices
let mut end_of_file = false;
while !end_of_file {
let bytes_read = file.read(&mut slice_buffer).unwrap();
if bytes_read != 0 {
let mut slice_vec: Vec<u8> = Vec::new();
bytes_in_last_row = bytes_read;
for i in 0..LEN {
slice_vec.push(slice_buffer[i]);
}
file_slices.push(slice_vec);
slice_buffer = [0u8; LEN];
} else {
end_of_file = true;
}
}
println!("Vector size is {} lines.", file_slices.len());
4条答案
按热度按时间gcuhipw91#
这里的
file_slices
是file
的引用集合。这节省了再次复制整个文件的时间,但意味着只要file_slices
存在,就不能删除file
。如果你想要一个深拷贝,你可以这样做:
cyvaqqii2#
既然你先读入一个数组,然后把这个数组复制到一个向量中,我建议你直接读入一个向量(长度是可调的,而不是一个常量,正如你所要求的)。
请注意,避免副本是通过与新向量交换(为下一个块做好准备)来完成的。
我尽可能地接近你最初的例子。
在你自己的回答中,你给出了关于最后一部分的细节;我做了相应的调整。
请注意,如果
read()
不是0
(它可能小于请求的数量),则无法保证read()
将准确返回chunk_length
,即使在文件的中间(不一定在最后)。如果返回值n小于缓冲区大小,即使读取器还没有到达流的末尾,也不是错误。例如,这可能是因为现在实际可用的字节数较少(例如,接近文件结尾),或者因为read()被信号中断。
8wigbo563#
使用
Vec
:let slice_buffer = vec![0; LEN]
,然后truncate
它到正确的大小,并把它直接在你的输出:klr1opcd4#
@prog-fh解决方案几乎解决了我的问题。由于它帮助我做到了这一点,我将其标记为“接受”。如果最后一个块的长度小于
chunk_length
,我的代码将添加零,所以我完全删除了chunk_count
并以这种方式简化了循环: