2009-07-03 128 views
2

我有一些非常大的整数数组,我想压缩。
但是这样做在Java中的方法是使用这样的事情 -压缩java中的整数数组

int[] myIntArray; 
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(1024); 
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new DeflaterOutputStream(byteArrayOutputStream)); 
objectOutputStream.writeObject(myIntArray); 

注意,int数组首先需要通过Java的转换为字节。 现在我知道速度很快,但它仍然需要创建一个全新的字节数组,并扫描整个原始int数组,将其转换为字节并将值复制到新的字节数组中。

有什么办法可以跳过字节转换,并立即压缩整数?

+0

你的int数组被转换为字节在哪里? ObjectOutputStream接受你的对象并直接序列化它。 DeflaterOutputStream压缩序列化结果,然后压缩结果存储在ByteArrayOutputStream中。我认为这正是你想要发生的...... – Stobor 2009-07-03 23:20:37

+0

在我的情况下,我想压缩的对象是一个int []数组。 序列化过程将其转换为字节,这是我想要跳过的步骤。 – pdeva 2009-07-04 01:11:07

回答

4

跳过ObjectOutputStream并直接将int s直接存储为每个四个byte s。例如DataOutputStream.writeInt是一个简单的方法来做到这一点。

2

嗯。除非有很多冗余,否则通用压缩算法不一定能够很好地压缩二进制值数组。根据您对数据的了解,您可能会更好地开发自己的产品。

这是什么,你真的试图压缩?

2

你可以使用由Protocol Buffers使用的representation。每个整数由1-5个字节表示,具体取决于其大小。

此外,新的“包装”的表示意味着你基本上是一个有点“头”说,这是多大(和它的哪些领域),然后只将数据。这可能是什么呢ObjectOutputStream为好,但它是一个新的创新在PB :)

注意,这将压缩基于幅度,基于整数是如何屡见不鲜。这将大大影响它是否对你有用。

0

一个字节数组不会为你节省很多内存,除非你把它作为一个持有unsigned ints的字节数组,这在Java中是非常危险的。它将用更多的处理时间替换内存开销,以便对代码进行步骤检查。这对于数据存储来说可能是正确的,但是那里已经有了数据存储解决方案。
除非你这样做是为了序列化的目的,否则我认为你正在浪费你的时间。

0

如果整数数组保证没有重复项,则可以使用java.util.BitSet。

作为其基础的实现是位的数组,与表示每个比特如果某个整数存在或不存在于位集合,其内存使用是相当低的,因此需要更小的空间被序列化。

0

在您的示例中,您正在将压缩流写入ByteArrayOutputStream。您的压缩数组需要存在某处,如果目标是内存,则ByteArrayOutputStream是您的可能选择。您也可以将流写入套接字或文件。在这种情况下,你不会在内存中复制流。如果您的阵列是800MB,并且您的阵列运行在1GB,那么您可以使用您包含的示例轻松将阵列写入压缩文件。该更改将用文件流替换ByteArrayOutputStream。

ObjectOutputStream格式实际上相当高效。它不会在内存中复制你的数组,并且有特殊的代码来有效地写数组。

想要在内存中使用压缩数组吗?你的数据是否适合稀疏数组?稀疏数组在你的数据有很大差距时是很好的。