我能否使用C#序列化来读取自定义格式的二进制文件?

4
我有一个自定义的二进制文件,我想将其读入我的C#程序。
有几种不同的格式,一些是MSB优先,一些是LSB优先,还有一些变量顺序不同。
目前,我有一个类,它逐个字节地读取正确数量的字节。
这很慢,所以我正在寻求任何可以提高性能的方法。
序列化是否可能表现更好?如果是这样,对于我所描述的情况,这是否可行?是否可以自定义BinaryFormatter以支持大/小端格式?
谢谢。
2个回答

2
你不能使用BinaryFormatter来完成该操作,因为它需要额外的元数据/填充对象。你需要手动从Stream或类似的二进制读取器中读取。

我曾经写过一些非常相似的代码,我会编写自己的读取器放在流的顶部,其中包括像ReadInt32LittleEndianReadInt32BigEndian等方法,使用移位(<< / >>)组装字节。但是,重要的是我会使用一个后备缓冲区来减少对底层流的调用次数(即使有缓冲区,这也可能是无法接受的慢)。

让我向你介绍一些来自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的实现:

  • Ensure确保我们在后备缓冲区中至少有4个字节(如果需要,则获取更多)
  • 我们增加一些计数器,以便跟踪我们在逻辑缓冲区中的位置
  • 我们从缓冲区中读取数据

一旦您为格式创建了阅读器,反序列化应该会容易得多。


0

不行,这样做不行。虽然可能可以,但是转换的开销很可能会影响性能。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接