我有以下格式的整数序列:
Integer1 Integer2 Integer3 Integer4 Integer5 ....
每四个连续整数对应于单个记录的值。所以,我无法真正订购它们。
压缩此类文件的最佳方法是什么?
更新
1-价值彼此独立。每4个连续的整数代表一个记录,例如:
CustomerId PurchaseId Products MoneySpent
每个都保持一个整数值。
2-理想情况下,我希望将其压缩为对象和磁盘。
由于
答案 0 :(得分:0)
最简单和最兼容的方法是在编写文件时通过使用GZIPOutputStream包装流并使用GZIPInputStream包装来对文件进行GZIP。
InputStream in = new BufferedInputStream(new GZIPInputStream(new FileInputStream(filename)));
OutputStream out = new BufferedOutputStream(new GZIPOutputStream(new FileOutputStream(filename)));
答案 1 :(得分:0)
使用GZip并非以给定方式最佳。由于您的OrderID,您的PurcaseId,ProductID和MoneySpent彼此不同,但所有OrderIds都有一些共同点,如PurcaseId,ProductId和MoneySpent。因此,最好将这些值存储为行而不是列。
由于您通常在此表中有一个排序顺序,您将要存储,一列可以用delta值表示。例如,如果按OrderId对值进行排序,则可以将10,23,44,53的序列表示为+ 10,+ 13,+ 21,+ 53。这些数字比原始数字更小,更容易重复。
整数值可以表示为可变位长信息。首先,存储值的位数和实际值。这样可以节省很多前导零。
对于花钱,您还可以考虑分数值的实际重复,如99,25,50,49等。产品的价格更有可能是49,99而不是51,23。因此,将货币整数分成两个值将使您能够使用霍夫曼编码并将特殊值视为符号,其余值作为游程长度位。
为了表示比特长度,您还可以使用不同的编码方案,再一次是64个符号的霍夫曼代码(64个不同长度的信息)并训练编码模式。通过这种方式,您将获得非常少的位数,而不是写入整数甚至是长整数。
其余的东西可以放到gzip中。这通常更好地取决于您表达位长度的方式,因为压缩前导零比不同的位长信息更容易,但每个压缩成本。
比特长度的另一种编码方案是使用最小最大值方法。
例如,对于上述序列10,23,44,53,我们存储10,+ 43(53),+ 13,+ 23。我们的想法是知道在10到53之间有43个元素。因此,下一个值的最大长度为6(2 ^ 6 = 64)位。这样就不需要比特长度信息。您只需将序列存储在oder的第一个最小值,下一个最大值,下一个最小值,下一个最大值等等。
更有效的方案是使用最小,最大,中间,中间左,中右,左中左,中左,右中左,右中......这样您就有机会获得最小的位长知识。使用这种方式可以得到非常小的整数,而无需额外的位长信息。
使用这样的方案通常会使GZip有机会进一步减少< 10%导致完全省略GZip。
[总结]
所以GZip很简单,如果你需要挤出更多的东西,那就去列明智而不是行/入口。使用每列的特殊知识。如果排序使用增量作为表示。使用由霍夫曼代码表示的比特长度信息(每列一个),并且使用产品价格的美分和美元值通常会产生非常好的压缩机会。通过增量存储已排序的列并使用树智能存储,从而非常了解下一个需要的位长度。