访问BinaryReader的内部缓冲区
问题描述:
我继承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
字段实施?
下面是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);
}
答
尝试访问内部缓冲区不是一个好主意。为什么不这样做:
var val = base.ReadUInt16();
return (ushort)((val << 8) | ((val >> 8) & 0xFF));
略多于从缓冲区直接读取慢,但我严重怀疑,这将会使你的应用程序的整体速度产生重大影响。
FillBuffer
显然是一个实现细节,由于某些原因,框架团队决定需要制作protected
,可能是因为其他一些Framework类利用BinaryReader
的内部工作。既然你知道它所做的只是填充内部缓冲区,而派生类不能访问内部缓冲区,所以如果你决定自己重写阅读实现,我建议你忽略这个方法。称它对你没有任何好处,并且会对你造成很大的伤害。
您可能会感兴趣的series of articles我几年前写的,其中我实现了一个BinaryReaderWriter
类,它本质上是一个BinaryReader
和BinaryWriter
连接在一起,并允许您底层流随机读/写访问。
你说在访问缓冲区之前需要调用该方法,但如果缓冲区根本无法访问呢?他们应该使这个方法成为内部的,或者提供一个getter包装到缓冲区。因为我处理大型二进制文件,所以我更喜欢性能,我只是忽略FillBuffer。请在你的回答中更具体地提及它,以便其他用户更清楚。你认为保存交换是多余的优化(我需要覆盖所有的数字阅读器)。 – Shimmy 2014-10-31 03:34:16
是的,我确实认为节省交换是冗余优化。与从磁盘文件读取数据所花费的时间相比,几百万次掉期不算什么。至于'FillBuffer'方法,我不担心它。这显然是一个实现细节,因为框架团队认为他们需要公开的某些未知原因。可能是因为不同的.NET类使用它。正如你所说,因为它的功能是填充派生类无法访问的内部缓冲区,所以调用它不会有什么好处。 – 2014-10-31 03:46:25
吉姆,包括'&0xFF'在内的点有什么意思?这不是没有使用它的结果吗?你可以请参考一篇文章解释吗? 顺便说一句,我刚刚订阅了你的博客,我喜欢它! – Shimmy 2014-10-31 04:40:54