为何read_exact报缓冲区读取失败?文件复制后大小一致却未出错
问题分析与解决
错误原因
你遇到的Failed to read from dst file: Error { kind: UnexpectedEof, message: "failed to fill whole buffer" }错误,根源在compare函数的逻辑缺陷:
- 每次从源文件读取数据后,不管实际读到的字节数(最后一次大概率小于指定的
read_size,比如你设置的512),你都调用dst_file.read_exact(&mut dst_block)强制读取满read_size字节的目标文件内容。 - 当源文件读完最后一段不足
read_size的数据时,目标文件也已经到了对应位置,此时read_exact无法读取到足够的字节,就会抛出UnexpectedEof错误。 - 而
write_to_file是按实际读取的字节数写入,所以文件大小和源文件完全一致,复制过程不会触发报错。
修复后的代码
修改compare函数,根据每次实际读取的字节数来读取目标文件内容:
fn compare<R: Read>( mut reader: R, read_size: usize, dst: &Path, ) { let mut dst_file = File::open(dst).expect("failed to open dst file"); let mut buffer_chunk = vec![0; read_size]; let mut dst_block = vec![0; read_size]; let mut bytes_read = read_size; while bytes_read > 0 { bytes_read = reader.read(&mut buffer_chunk).expect("failed to read from src file"); if bytes_read > 0 { // 仅读取与源文件当前块实际长度匹配的内容 let dst_bytes_read = dst_file.read(&mut dst_block[..bytes_read]).expect("Failed to read from dst file"); // 确保目标文件读取的字节数与源文件一致 assert_eq!(dst_bytes_read, bytes_read, "dst file has unexpected length"); if buffer_chunk[..bytes_read] != dst_block[..bytes_read] { eprintln!("contents are different"); } } } println!("same"); }
额外优化建议
- 可以直接使用
std::io::copy替代自己实现的write_to_file,标准库的实现更高效且经过充分测试。 - 在
get_entry函数中,直接忽略entry.path()的错误可能会导致漏找目标文件,建议适当处理该错误而非直接用ok()跳过。
内容的提问来源于stack exchange,提问作者Harry
相关产品推荐
相关产品推荐

