我有这个使用Java的Deflator / Inflator的Scala代码。
def compress(bytes: Array[Byte]): Array[Byte] = {
val deflater = new java.util.zip.Deflater
val baos = new ByteArrayOutputStream
val dos = new DeflaterOutputStream(baos, deflater)
dos.write(bytes)
baos.close
dos.finish
dos.close
baos.toByteArray
}
def decompress(bytes: Array[Byte]): String /*Array[Byte]*/ = {
val deflater = new java.util.zip.Inflater()
val baos = new ByteArrayOutputStream(512)
val bytesIn = new ByteArrayInputStream(bytes)
val in = new InflaterInputStream(bytesIn, deflater)
var go = true
while (go) {
val b = in.read
if (b == -1)
go = false
else
baos.write(b)
}
baos.close
in.close
// String(byte[] bytes, Charset charset)
new String(baos.toByteArray, "ASCII")
}
我需要压缩只有一位(来自13 x 8 = 104位的第100位)设置的BitSet。
val bs = new util.BitSet()
bs.set(100)
val ba = bs.toByteArray
val z = gzip.compress(ba)
println(ba.size)
println(ba.mkString(":"))
println(z.size)
println(z.mkString(":"))
我希望减少一些戏剧性的尺寸,但结果是我只保存了一个字节。
13
0:0:0:0:0:0:0:0:0:0:0:0:16
12
120:-100:99:96:64:0:1:0:0:29:0:17
这是Java解压缩器的预期结果吗?这种情况下有更好的压缩机吗?
答案 0 :(得分:1)
我认为问题是GZIP编码数据包含占用字节的头信息。这并不重要,因为要压缩的数据大小通常要大得多。
如果你有大多数零(或任何相同值的运行)和几个字节的其他东西,也许运行长度编码更好。
如果你真的只有1位设置,那么你可以想出你自己的编码,如果bitSet是固定长度,它只编码那个单位的偏移。
答案 1 :(得分:1)
这是Java解压缩器的预期结果吗?
这是我所期待的。 " deflate"压缩算法是为压缩大文件而设计的。对于一个小文件(13个字节),编码中的开销可能会平衡(甚至超过)所实现的压缩。
这种情况有没有更好的压缩机?
我不希望标准Java库支持的任何压缩算法做得更好。如果你想在微小的位图上获得良好的性能,你可能需要从第一原理设计自定义压缩器。
例如,稀疏位图可以表示为数字序列(在本例中为byte
值),表示已设置的位,或表示连续运行的数字序列或零。