我有一个自定义二进制文件,我想读入我的C#程序.
有几种不同的格式,一些MSB优先,一些LSB优先,一些具有不同顺序的变量.
目前,我有一个类,它一次读取一个正确的字节数.
它非常慢,所以我希望以任何方式提高性能.
序列化可能表现更好吗?如果是这样,这可能与我已经解决的情况有关吗?是否可以为大/小端格式自定义BinaryFormatter?
谢谢.
最佳答案 你不能用BinaryFormatter做到这一点 – 它会期望在对象周围增加元数据/填充.您必须从Stream手动读取或类似地通过二进制读取器读取.
完成了一些非常相似的代码后,我会编写自己的读取器,它位于流的顶部,使用以下方法:ReadInt32LittleEndian,ReadInt32BigEndian(等等,用于所需的一切) – 并使用shift(<<< />>)组装字节.但重要的是,我会使用一个后备缓冲区来减少对底层流的调用量(即使使用缓冲区,这也会慢得令人无法接受).
让我举几个来自protobuf-net的代码来做这个…特别是ProtoReader
,举一个例子:
/// <summary>
/// Reads an unsigned 32-bit integer from the stream; supported wire-types: Variant, Fixed32, Fixed64
/// </summary>
public uint ReadUInt32()
{
switch (wireType)
{
case WireType.Variant:
return ReadUInt32Variant(false);
case WireType.Fixed32:
if (available < 4) Ensure(4, true);
position += 4;
available -= 4;
return ((uint)ioBuffer[ioIndex++])
| (((uint)ioBuffer[ioIndex++]) << 8)
| (((uint)ioBuffer[ioIndex++]) << 16)
| (((uint)ioBuffer[ioIndex++]) << 24);
case WireType.Fixed64:
ulong val = ReadUInt64();
checked { return (uint)val; }
default:
throw CreateException();
}
}
(这里的wireType广泛地充当了字节序等的指示符,但这并不重要)
看看Fixed32的实现:
>确保我们的后备缓冲区中至少还有4个字节(如果需要,可以获取更多字节)
>我们增加一些计数器,以便我们可以在逻辑缓冲区中跟踪我们的位置
>我们从缓冲区读取数据
你有一个阅读器,你的格式,反序列化应该更容易.