29

允许在文件中随机读/写的最佳压缩算法是什么?

我知道任何自适应压缩算法都是不可能的。

而且我知道霍夫曼编码是不可能的。

有没有人有更好的压缩算法来允许随机读/写?

我认为如果你将它写成块,你可以使用任何压缩算法,但理想情况下我不希望一次解压缩整个块。但是,如果您对执行此操作的简单方法以及如何知道块边界有任何建议,请告诉我。如果这是您的解决方案的一部分,请让我知道当您要读取的数据跨越块边界时您会做什么?

在您的答案的上下文中,请假设有问题的文件是 100GB,有时我想读取前 10 个字节,有时我想读取最后 19 个字节,有时我想读取 17中间的字节。.

4

6 回答 6

29

我对暗示这种事情是不可能的回应的数量感到震惊。

难道这些人从来没有听说过“压缩文件系统”吗?自 1993 年微软因压缩文件系统技术被 Stac Electronics 起诉之前就已经存在了?

我听说LZSLZJB是人们实现压缩文件系统的流行算法,它们必然需要随机访问读取和随机访问写入。

也许最简单和最好的做法是为该文件打开文件系统压缩,让操作系统处理细节。但是如果你坚持手动处理,也许你可以通过阅读NTFS 透明文件压缩来获得一些技巧。

另请查看: “StackOverflow:对档案内随机访问具有良好支持的压缩格式?”

于 2010-08-08T05:20:32.853 回答
4

razip 格式支持随机访问读取,其性能比 gzip/bzip2 更好,而 gzip/bzip2 必须对此支持进行调整:

http://sourceforge.net/projects/razip/

于 2011-08-23T15:23:58.473 回答
3

基于字典的压缩方案,每个字典条目的代码以相同大小编码,将导致能够以代码大小的任意倍数开始读取,并且如果代码不使用其上下文,则写入和更新很容易/邻居。

如果编码包括区分代码开头或结尾的方法,那么您不需要代码长度相同,您可以从文件中间的任何位置开始读取。如果您从流中的未知位置读取,此技术会更有用。

于 2008-11-06T10:03:18.570 回答
3

我认为 Stephen Denne 可能在这里有所作为。想象:

  • 类似 zip 的序列压缩到代码
  • 字典映射代码 -> 序列
  • 文件就像一个文件系统
    • 每次写入都会生成一个新的“文件”(字节序列,根据字典压缩)
    • “文件系统”跟踪哪个“文件”属于哪个字节(开始,结束)
    • 每个“文件”都根据字典进行压缩
    • 根据“文件系统”读取工作文件,解压缩和检索字节
    • 写入使“文件”无效,附加新的“文件”以替换无效的文件
  • 该系统将需要:
    • 文件系统的碎片整理机制
    • 不时压缩字典(删除未使用的代码)
  • 正确完成后,可以在无人看管时(空闲时间)或通过创建新文件并最终“切换”来完成内务管理

一个积极的影响是字典将适用于整个文件。如果您可以节省 CPU 周期,您可以定期检查与“文件”边界重叠的序列,然后重新组合它们。

这个想法适用于真正的随机读取。如果您只打算阅读固定大小的记录,那么这个想法的某些部分可能会变得更容易。

于 2010-07-30T14:56:53.513 回答
1

我不知道任何允许随机读取的压缩算法,更不用说随机写入了。如果您需要这种能力,最好的办法是将文件压缩成块而不是整体。

例如
,我们将首先查看只读情况。假设您将文件分成 8K 块。您压缩每个块并按顺序存储每个压缩块。您需要记录每个压缩块的存储位置和大小。然后,假设您需要从偏移量 O 开始读取 N 个字节。您需要确定它在哪个块中(O / 8K),解压缩该块并获取这些字节。您需要的数据可能跨越多个块,因此您必须处理这种情况。

当您希望能够写入压缩文件时,事情会变得复杂。您必须处理越来越大的压缩块。您可能需要为每个块添加一些额外的填充以防它扩展(它仍然是未压缩的相同大小,但不同的数据将压缩为不同的大小)。如果压缩数据太大而无法放回给定的原始空间,您甚至可能需要移动块。

这基本上就是压缩文件系统的工作方式。您最好为文件打开文件系统压缩并正常读取/写入它们。

于 2008-10-25T13:51:03.003 回答
1

压缩就是从数据中删除冗余。不幸的是,冗余不太可能以单调的均匀度分布在整个文件中,这是您可以预期压缩细粒度随机访问的唯一场景。

但是,您可以通过维护一个在压缩期间构建的外部列表来接近随机访问,该列表显示未压缩数据流中的选定点与其在压缩数据流中的位置之间的对应关系。您显然必须选择一种方法,其中源流与其压缩版本之间的转换方案不会随流中的位置而变化(即没有 LZ77 或 LZ78;相反,您可能想要使用 Huffman 或字节-对编码。)显然,这会产生很多开销,并且您必须决定如何在“书签点”所需的存储空间和从 a 开始解压缩流所需的处理器时间之间进行权衡书签点以获取您的数据

至于随机访问写作……那几乎是不可能的。如前所述,压缩是关于从数据中删除冗余。如果您尝试用不具有相同冗余的数据替换可能已经被压缩的数据,因为它是冗余的,那么它根本不适合。

但是,取决于您要进行多少随机访问写入——您可以通过维护一个稀疏矩阵来模拟它,该矩阵表示压缩后写入文件的所有数据。在所有读取中,您将检查矩阵以查看您是否正在读取压缩后写入的区域。如果没有,那么您将转到数据的压缩文件。

于 2008-11-04T04:35:54.067 回答