【发布时间】:2011-08-11 13:48:45
【问题描述】:
我想编写一个存储后端来存储更大的数据块。数据可以是任何东西,但主要是二进制文件(图像、pdf、jar 文件)或文本文件(xml、jsp、js、html、java...)。我发现大部分数据已经被压缩了。如果全部压缩,大约可以节省 15% 的磁盘空间。
我正在寻找一种最有效的算法,该算法可以高概率地预测可以压缩或不压缩数据块(比如 128 KB)(无损压缩),而无需尽可能查看所有数据。
压缩算法将是 LZF、Deflate 或类似的算法(可能是 Google Snappy)。所以预测数据是否可压缩应该比压缩数据本身要快得多,并且使用更少的内存。
我已经知道的算法:
尝试压缩数据的一个子集,比如说 128 字节(这有点慢)
计算 128 字节的总和,如果在一定范围内则可能不可压缩(在 128 * 127 的 10% 以内)(这个速度很快,也比较好,但我正在寻找一些东西更可靠,因为该算法实际上只查看每个字节的最高位)
看文件头(比较靠谱,但感觉像作弊)
我猜大体的想法是,我需要一个能够快速计算出字节列表中每个位的概率是否大约为 0.5 的算法。
更新
我已经实现了“ASCII 检查”、“熵计算”和“简化压缩”,并且都给出了很好的结果。我想改进算法,现在我的想法是不仅要预测数据是否可以压缩,还要预测可以压缩多少。可能使用算法的组合。现在,如果我只能接受多个答案...我将接受给出最佳结果的答案。
仍然欢迎其他答案(新想法)!如果可能的话,提供源代码或链接:-)
更新 2
类似的方法是now implemented in Linux。
【问题讨论】:
-
您可以尝试统计方法(您显然已经考虑过)或根据文件类型事先进行一些估计。我会选择第二个选项并对此进行改进。
-
嗯,是的,但究竟是哪种统计方法?
-
我发现如果一个块是可压缩的,查看前 128 个字节就足以得到一个很好的预测。但这只是一个例子。
-
如果您主要处理完整的文件,而不是使用文件头,甚至可能只处理前 4 个字节,以识别已知的压缩文件格式。 linux file 命令使用一个非常广泛的魔法模式数据库,您可以从中提取所需的信息。
-
@Thomas 不确定前 128 个字节。某些格式在此处具有可压缩的标头。例如。 JAR/zip 文件有文件名列表,主要类似于纯文本,但它有压缩内容。也许值得在整个区块中采样几个小区块。
标签: java compression