【问题标题】:Protobuf Exception When Deserializing Large File反序列化大文件时出现 Protobuf 异常
【发布时间】:2014-05-09 11:05:47
【问题描述】:

我正在使用 protobuf 将大对象序列化为二进制文件,以便反序列化并在以后再次使用。但是,我在反序列化一些较大的文件时遇到了问题。这些文件的大小约为 2.3 GB,当我尝试反序列化它们时,会抛出几个异常(按以下顺序):

我查看了第二个例外中提到的问题,但这似乎并未涵盖我遇到的问题。

我正在使用 Microsoft 的 HPC 包来生成这些文件(它们需要一段时间),因此序列化如下所示:

   using (var consoleStream = Console.OpenStandardOutput())
   {
            Serializer.Serialize(consoleStream, dto);
   }

我正在阅读以下文件:

    private static T Deserialize<T>(string file)
    {
        using (var fs = File.OpenRead(file))
        {
            return Serializer.Deserialize<T>(fs);
        }
    }

文件是两种不同的类型。一个大小约为 1GB,另一个约为 2.3GB。较小的文件都可以工作,而较大的文件则不能。任何想法这里可能出了什么问题?我意识到我没有提供很多细节,可以根据要求提供更多。

【问题讨论】:

  • 反序列化2.3 GB已经听错了。忽略错误,对如此 huge 数据量使用任何类型的序列化的想法是不好的。您能否详细说明您想通过使用序列化解决什么问题?
  • @Sinatr 是的,我已经意识到这可能不是最好的路线,但我现在有文件,所以试图挽救它们。我需要能够生成这些文件并将它们保存到磁盘以供以后使用。
  • 有什么用?你能准确地说出这些文件是什么吗?也许您决定通过使用序列化或其他方式传输(导出/导入?)数据,其中序列化(对于如此数量的数据)是一个坏主意。考虑使用自定义文件格式,大数据(HPC包?那是什么?)只是1对1复制,而小部分(包含配置,路径,参数等)以经典方式序列化,然后与大数据组合.
  • @geekchic 我必须承认,我的单元测试套件没有扩展到多 GB 文件。这可能只是与int 相关的读者问题,可能应该是long;我得找个时间调查一下。
  • @MarcGravell 但你必须承认:这是一个很酷的错误!也许还有一个检查算术编译器选项的案例。

标签: c# protobuf-net


【解决方案1】:

这里需要参考一下最近在protobuf list上的讨论:

Protobuf 使用 int 来表示大小,因此它可能支持的最大大小是

猜测 protobuf-net 内部失败的原因基本相同。我可能可以更改 protobuf-net 以支持更大的文件,但我必须建议这是推荐,因为看起来没有其他实现可以很好地处理如此庞大的数据。

修复可能只是在读取器/写入器层中将大量int 更改为long 的情况。但是:您的数据的布局是什么?如果有一个外部对象基本上是 实际 对象的列表,则可能有一种使用增量读取器的偷偷摸摸的方法(基本上,直接欺骗 repeated 支持)。

【讨论】:

  • 有一个外部对象,上面有几个(相当大的)字典。这样的读者究竟会如何工作?
  • 基本上,使用外部阅读器读取项目的长度,使用内部阅读器读取它们;但是,查看代码,可能ProtoReader.positionProtoReader.blockEnd 更新为long,确保还将任何相关的int.MaxValue 更改为long.MaxValue。您可能在某处有示例生成器或示例吗?我当然可以尝试编写一个多 GB 的生成器,但问一下也无妨……
  • 恐怕我不知道,代码(和数据)属于我的雇主。我想同时我会重新生成文件并将其分解成更小的块。
  • @geekchic 这真的取决于你有多迫切需要它;我可以试试看,但是在很多项目之间平衡时间总是很有趣...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-09
  • 2013-12-12
  • 1970-01-01
相关资源
最近更新 更多