You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 20:05:02