访问BinaryReader的内部缓冲区

时间:2014-10-30 02:24:34

标签: c# binary endianness binaryreader

我继承了BinaryReader类。

我必须覆盖一些基本方法,例如ReadUInt16

此方法的内部实现是:

public virtual ushort ReadUInt16(){
   FillBuffer(2);
   return (ushort)(m_buffer[0] | m_buffer[1] << 8);
}

我读取的二进制文件被组织为高字节优先(大端),我也从BinaryReader继承,因为我必须添加更多功能。 无论如何,我想在子类本身实现交换。

是否有其他方式可以在不使用反射或其他消耗资源的情况下访问m_buffer或替代方案? 可能是我应该覆盖FillBuffer并备份偷看的字节?或者只是忽略它?它会有副作用吗?以前有人遇到过这个吗?任何人都可以解释为什么FillBuffer不是内部的?是否需要始终填充缓冲区或者可以跳过它?既然它不是内部的,为什么不能实现对m_buffer字段实施的受保护的getter?

这是FillBuffer的实施。

protected virtual void FillBuffer(int numBytes) {
    if (m_buffer != null && (numBytes < 0 || numBytes > m_buffer.Length)) {
        throw new ArgumentOutOfRangeException("numBytes", 
            Environment
            .GetResourceString("ArgumentOutOfRange_BinaryReaderFillBuffer"));
    }
    int bytesRead=0;
    int n = 0;

    if (m_stream==null) __Error.FileNotOpen();

    // Need to find a good threshold for calling ReadByte() repeatedly
    // vs. calling Read(byte[], int, int) for both buffered & unbuffered
    // streams.
    if (numBytes==1) {
        n = m_stream.ReadByte();
        if (n==-1)
            __Error.EndOfFile();
        m_buffer[0] = (byte)n;
        return;
    }

    do {
        n = m_stream.Read(m_buffer, bytesRead, numBytes-bytesRead);
        if (n==0) {
            __Error.EndOfFile();
        }
        bytesRead+=n;
    } while (bytesRead<numBytes);
}

1 个答案:

答案 0 :(得分:4)

尝试访问内部缓冲区不是一个好主意。为什么不这样做:

var val = base.ReadUInt16();
return (ushort)((val << 8) | ((val >> 8) & 0xFF));

比直接从缓冲区读取的速度稍慢,但我非常怀疑这会对应用程序的整体速度产生重大影响。

FillBuffer显然是一个实现细节,由于某种原因,Framework团队决定他们需要生成protected,这可能是因为其他一些Framework类利用了BinaryReader的内部工作原理。既然你知道它所做的就是填充内部缓冲区,你的派生类也无法访问内部缓冲区,所以如果你决定自己重写阅读实现,我建议你忽略那种方法。打电话给你可以做任何好事,并且可以给你带来很大的伤害。

您可能对我几年前写过的series of articles感兴趣,其中我实施了一个BinaryReaderWriter类,基本上是BinaryReaderBinaryWriter连接在一起,并允许您对基础流进行随机读/写访问。