我可以使用C#Serialization以自定义格式读取二进制文件吗?

时间:2010-11-11 12:08:56

标签: c# serialization binary-data

我有一个自定义二进制文件,我想读入我的C#程序。

有几种不同的格式,一些MSB优先,一些LSB优先,一些具有不同顺序的变量。

目前,我有一个类,它一次读取一个正确的字节数。

速度非常慢,所以我希望尽我所能提高性能。

序列化可能表现更好吗?如果是这样,这可能与我已经解决的情况有关吗?是否可以为big / little-endian格式自定义BinaryFormatter?

感谢。

2 个答案:

答案 0 :(得分:2)

你无法用BinaryFormatter做到这一点 - 它会期望在对象周围添加额外的元数据/填充。您必须从Stream或类似地通过二进制阅读器手动阅读。

完成了一些非常相似的代码后,我会编写自己的阅读器,它位于流的顶部,使用的方法包括:ReadInt32LittleEndianReadInt32BigEndian(等等,用于所需的一切) - 并使用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实施:

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

你有一个阅读器,你的格式,反序列化应该更容易。

答案 1 :(得分:0)

不,它不会工作。嗯,它可以,但转型的开销可能会破坏性能。