Java:将大量数据序列化到单个文件中

时间:2008-09-24 20:22:20

标签: java serialization

我需要将大量数据(大约2gig)的小对象序列化到一个文件中,以便稍后由另一个Java进程处理。表现很重要。有人能提出一个很好的方法来实现这个目标吗?

9 个答案:

答案 0 :(得分:4)

您是否看过谷歌的protocol buffers?听起来像是一个用例。

答案 1 :(得分:4)

我不知道为什么Java Serialization被拒绝,这是一个完全可行的机制。

从原始帖子中不清楚,但同时堆中的所有2G数据都是?或者你正在抛弃其他东西?

开箱即用,序列化不是“完美”的解决方案,但如果在对象上实现Externalizable,则序列化可以正常工作。序列化的大开支是弄清楚要写什么以及如何编写它。通过实施Externalizable,您可以轻松地执行这些决策,从而大大提高性能并节省空间。

虽然I / O是编写大量数据的主要成本,但转换数据的偶然成本也非常昂贵。例如,您不希望将所有数字转换为文本然后再转回,如果可能,最好以更原生的格式存储它们。 ObjectStream具有在Java中读/写本机类型的方法。

如果您的所有数据都被设计为加载到单个结构中,那么在实现Externalizable之后,您可以简单地执行ObjectOutputStream.writeObject(yourBigDatastructure)。

但是,您也可以迭代结构并在各个对象上调用writeObject。

无论哪种方式,你都需要一些“objectToFile”例程,也许需要几个。这实际上是Externalizable提供的,以及构建结构的框架。

另一个问题当然是版本控制等等。但是既然你自己实现了所有的序列化例程,那么你也完全可以控制它。

答案 2 :(得分:0)

您是否尝试过java序列化?您可以使用ObjectOutputStream将其写出来,然后使用ObjectInputStream重新阅读。当然这些课程必须是Serializable。这将是低成本的解决方案,并且因为对象以二进制形式存储,所以它将是紧凑且快速的。

答案 3 :(得分:0)

我想到的最简单的方法是使用NIO的内存映射缓冲区(java.nio.MappedByteBuffer)。使用与一个对象的大小相对应的单个缓冲区(大约),并在必要时将它们刷新/附加到输出文件。内存映射缓冲区非常有效。

答案 4 :(得分:0)

协议缓冲区:有意义。这是他们的维基的摘录:http://code.google.com/apis/protocolbuffers/docs/javatutorial.html

获得更快的速度

默认情况下,协议缓冲区编译器尝试使用反射生成较小的文件来实现大多数功能(例如解析和序列化)。但是,编译器还可以为您的消息类型生成明确优化的代码,通常可以提供一个数量级的性能提升,但也会使代码的大小加倍。如果分析显示您的应用程序在协议缓冲区库中花费了大量时间,则应尝试更改优化模式。只需将以下行添加到.proto文件中:

选项optimize_for = SPEED;

重新运行协议编译器,它将生成极快的解析,序列化和其他代码。

答案 5 :(得分:0)

如果性能非常重要,那么您需要自己编写。您应该使用紧凑的二进制格式。因为2 GB的磁盘I / O操作非常重要。如果您使用任何人类可读格式(如XML或其他脚本),则可以使用2或更多因子调整数据大小。

根据数据,如果您以低压缩率动态压缩数据,可以加快速度。

Java序列化完全没有用,因为在读取Java时检查每个对象是否是对现有对象的引用。

答案 6 :(得分:0)

我开发了JOAFIP作为数据库替代方案。

答案 7 :(得分:0)

Apache Avro可能也很有用。它的设计独立于语言,并具有the popular languages的绑定。

检查出来。

答案 8 :(得分:-1)

您应该考虑使用数据库解决方案 - 所有数据库都会优化其信息,如果您使用Hibernate,则保持对象模型不变,甚至不考虑您的数据库(我相信这就是为什么它被称为休眠,只需存储您的数据,然后将其恢复原状)