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

C#中FileStream.Read读取最后块异常与File.ReadAllBytes结果不一致

问题分析与修复方案

我一眼就看出问题所在了——你在循环里错误地遍历了整个read_buff数组,但**FileStream.Read()返回的count值才是本次读取到的有效字节数**。

举个例子:如果你的文件总长度是150字节,第一次Read()会读满100字节,第二次Read()只会读取剩下的50字节,这时候read_buff的后50个位置还是第一次读取残留的数据。你现在的代码把整个数组都遍历了,等于把这50个旧数据也塞进了StringBuilder,结果自然和File.ReadAllBytes()一次性读取所有正确字节的结果对不上。

下面是修正后的完整代码,重点修改了遍历的范围,同时加上了using语句确保文件流被正确释放:

int limit = 0;
if (openFileDlg.FileName.Length > 0)
{
    fileName = openFileDlg.FileName;
    // 使用using自动释放FileStream资源,避免文件被占用
    using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
    {
        fsLen = (int)fs.Length;
        int count = 0;
        limit = 100;
        byte[] read_buff = new byte[limit];
        StringBuilder sb = new StringBuilder();
        
        while ((count = fs.Read(read_buff, 0, limit)) > 0)
        {
            // 只处理本次实际读取的count个字节,跳过数组中未被覆盖的旧数据
            for (int i = 0; i < count; i++)
            {
                byte b = read_buff[i];
                sb.Append(b.ToString("X2")); // 转成两位大写十六进制,和一次性读取的格式对齐
                // 如果需要字节间加空格,可改为 sb.Append($"{b:X2} ");
            }
        }
        
        // 这里可以用sb.ToString()获取正确的十六进制字符串
    }
}

另外补充两个细节:

  • 转十六进制时用ToString("X2")可以保证每个字节输出两位,比如字节0x05会被转成"05",和File.ReadAllBytes()遍历转换的逻辑完全一致。
  • 永远记得用using包裹文件流这类实现了IDisposable的对象,不然容易出现文件被锁定的问题。

内容的提问来源于stack exchange,提问作者NWOWN

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 07:03:48