反序列化大文件时出现Protobuf异常
本文关键字:Protobuf 异常 文件 反序列化 | 更新日期: 2023-09-27 18:02:28
我使用protobuf将大型对象序列化为二进制文件,以便进行反序列化,并在以后再次使用。但是,在对一些较大的文件进行反序列化时,我遇到了一些问题。这些文件的大小大约为2.3 GB,当我试图对它们进行反序列化时,我得到了几个异常(按以下顺序):
- 子消息读取不正确
- 无效钢丝式;这通常意味着你覆盖了一个文件而没有截断或设置长度;参见使用Protobuf-net,我突然得到一个关于未知线类型的异常
- 源数据中未预料到的端组;这通常意味着源数据已损坏
我已经看了第二个例外中提到的问题,但这似乎没有涵盖我遇到的问题。
我使用微软的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。较小的文件都可以工作,较大的文件则不行。你知道这里出了什么问题吗?我意识到我没有给出很多细节,可以根据要求提供更多。
这里我需要参考最近关于protobuf列表的讨论:
Protobuf使用int表示大小,因此它可能支持的最大大小是<2G。我们没有计划在代码中将int改为size_t。用户应避免使用过大的消息。
我猜测 protobuf-net内部故障的原因基本相同。我可能会改变protobuf-net来支持更大的文件,但我必须建议这是不建议,因为看起来没有其他实现可以很好地处理如此大的数据。
修复是可能是只是在读写层将大量int
更改为long
的情况。但是:数据的布局是怎样的呢?如果有一个外部对象,它基本上是一个实际对象的列表,那么可能有一种使用增量读取器的偷偷摸摸的方法(基本上,直接欺骗repeated
支持)。