2009-07-03 58 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格式實際上相當高效。它不會在內存中複製你的數組,並且有特殊的代碼來有效地寫數組。

想要在內存中使用壓縮數組嗎?你的數據是否適合稀疏數組?稀疏數組在你的數據有很大差距時是很好的。