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

BinaryReader调用ReadUInt16时Position<Length却抛EndOfStreamException的原因

为什么BinaryReader在Position=20、Length=174时调用ReadUInt16()会抛出EndOfStreamException?

这个问题看起来有点反直觉——按说174-20=154字节的剩余量,完全够读2字节的UInt16,但实际触发了末尾异常,大概率是这几个原因之一:

1. 流的Position或Length在你检查后被偷偷修改了

你可能是先查看了BaseStream.Position和BaseStream.Length,然后才调用ReadUInt16(),但这中间可能有其他代码(甚至是其他线程)修改了流的位置,或者流的实际长度被改变了(比如文件被外部程序截断、网络流的传输中断)。

举个例子:如果是文件流,你刚查完Length=174,紧接着另一个进程把文件改成了21字节,那此时剩余字节只有1,自然读不了2字节的UInt16。

2. 流的Length属性不是实时的“可用字节数”

有些流类型(比如NetworkStream、某些自定义流)的Length属性返回的是预期总长度,而不是当前实际可读取的字节数。比如网络流可能告诉你总共有174字节要传,但此时只传了20字节,剩下的还在路上——这时候调用ReadUInt16(),流根本拿不出额外的2字节,就会抛出异常。

3. BinaryReader的内部缓冲机制导致的问题

BinaryReader有自己的内部缓冲区,FillBuffer方法会尝试一次性读取指定数量的字节(这里是2)。如果流实际返回的字节数小于要求的数量(比如流突然中断,返回0字节),就会直接抛出EndOfStreamException,哪怕你之前算的剩余字节数是足够的。

怎么排查和解决?

  • 在调用前实时检查剩余字节:不要依赖之前的Position和Length值,在调用ReadUInt16()前重新计算:
    long remainingBytes = reader.BaseStream.Length - reader.BaseStream.Position;
    if (remainingBytes < 2)
    {
        // 处理字节不足的情况,比如返回默认值或抛出更明确的异常
        Console.WriteLine("剩余字节不足,无法读取UInt16");
        return;
    }
    ushort result = reader.ReadUInt16();
    
  • 检查流的类型和状态:如果是文件流,确认文件没有被其他进程修改;如果是网络流,先确保数据已经全部接收完毕;如果是MemoryStream,检查是否有代码意外截断了流。
  • 手动读取字节测试:可以先尝试用ReadByte()读取两次,看看是否能拿到有效字节:
    int b1 = reader.ReadByte();
    int b2 = reader.ReadByte();
    if (b1 == -1 || b2 == -1)
    {
        // 流已经到末尾了
    }
    else
    {
        ushort result = (ushort)((b2 << 8) | b1); // 注意端序,和ReadUInt16逻辑一致
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 04:00:26