【问题标题】:Random-access compression in common use?常用的随机访问压缩?
【发布时间】:2021-09-25 11:14:19
【问题描述】:

是否有用于随机访问压缩、只读或读写的标准库或 unix 工具?随机访问是指您可以读取或写入压缩内容的任何部分。

有很多流媒体工具(gzip、xz 等)和一些基于存档成员的工具 (zip),但我一般只知道关于随机访问的学术工作。存档的主要问题是它们通常单独压缩每个文件(没有跨文件的重复数据删除)。

Compression formats with good support for random access within archives? 有点相关,但因为已经过了 10 年,所以重新询问。

【问题讨论】:

    标签: compression


    【解决方案1】:

    对于问题的“读取”部分,您可以为大型压缩文件建立索引,该文件会在压缩数据中创建一组入口点。这些入口点的数量和密度决定了在获得所需内容之前需要解压缩多少数据,从而决定了随机访问的速度。请注意,all 压缩数据可以随机访问,因为您总是在开始时有一个入口点。你只需解压,直到你得到你想要的。那么随机读取访问不是能力问题,而是速度问题。

    zran.c 提供了为 gzip 或 zlib 流构建此类索引的示例。您可以对任何压缩数据格式执行此操作。同样pigz 将使用--independent 选项创建一个带有标记入口点的gzip 流。 bzip2 format 已经为每个块标记了入口点,其中入口是相隔几百 K 字节的未压缩数据。

    至于“或写”,这是一个完全不同的问题。我不知道有利于随机写入压缩数据的格式。通常,要获得任何级别的体面压缩,压缩数据取决于它之前的所有数据。所以如果你写在中间,你需要解压并重新压缩后面的所有数据。

    要拥有真正的随机写入访问权限,该格式必须解决两个问题。第一种是对压缩数据进行分块,如 bzip2 或 pigz 的独立选项,以打破对先前数据的依赖。如果您不经常这样做,则对压缩比的影响很小。然后你可以取一个块,解压缩它,做你的随机写入,然后重新压缩它。块越小,这种随机写入访问的速度就越快,但您必须权衡较小块的压缩率影响。

    要解决的第二个问题与文件系统具有相同的问题,即允许碎片和非顺序顺序。您希望避免必须重写压缩数据中的所有后续块,因为新随机写入的块变得更小或更大。如果您确实进行了重写,那么您将回到随机写入,所花费的时间与压缩流的大小成正比。解决方案是编写您自己的小文件系统,该系统内置于压缩数据格式中,允许块在流中不按顺序排列,并且流中存在未使用的间隙。我知道没有这样做的格式,但原则上可以实现。

    如果您将写入权限限制为附加,例如压缩日志的情况,则有针对现有格式的解决方案。 gzlog 是附加到 gzip 流的示例,允许高效附加少量数据,在每次附加后留下有效的 gzip 流。

    【讨论】:

    • 感谢您的链接,尽管如果我尝试通过文件间压缩来节省空间,则需要对“入口点”方法进行权衡。
    • Re possible 格式,这不是真正的问题(因为我问的是可用的),但我认为这很有趣。 IMO 您正在以一种非常基于流的方式思考。是的,据我所知,这是目前的情况,但我看不出有任何理由需要以这种方式进行文件压缩。有一些可能的格式与这种方法大相径庭。想象一个去重块的索引,或者有基于学术语法的方法。考虑更多磁盘搜索:)。 lrzip(基于 rsync)保留了一个无限大小的 LZ77 风格的“输出”,您可以参考,作为一个真实的例子。
    • 不,zran.c 创建的入口点具有每个入口点所需的历史记录。对压缩没有影响。除了保存入口点信息的内存之外,没有任何权衡。
    • (抱歉,cmets 的文本限制太小了,我不得不拆分内容,并且没有我本来可以做到的那么清楚。)我参考的权衡是存储更大的大小,如果您单独压缩存档成员(如 .zip),而不是为每个入口点添加 32K 的磁盘存储。可能我误解了 zran.c 的工作原理?或者,也许您想为某些应用程序每次重新生成索引,而不是持久化它?
    • 是的,我所说的随机访问是指一个应用程序多次随机访问压缩文件,将索引保存在内存中。
    猜你喜欢
    • 2012-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-10
    • 2015-05-05
    • 1970-01-01
    • 1970-01-01
    • 2010-11-13
    相关资源
    最近更新 更多