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
相关产品推荐
相关产品推荐

