【问题标题】:Compressing redundant file data压缩冗余文件数据
【发布时间】:2020-09-25 21:52:44
【问题描述】:

我有一个巨大的 ASCII 文件:

235M Apr 16 06:50 file

我做了以下步骤:

cat file > file_all

cat file >> file_all

470M Apr 16 06:51 file_all

file_1_2 的大小是 2 * file_1 的大小 = 470

我使用zip压缩命令压缩file_1和file_all:

25M Apr 16 06:08 file_all.gz

49M Apr 16 06:25 file_all.gz

据我了解,压缩算法有以下概念:

ZIP 压缩基于要压缩的数据中的重复模式 压缩,并且文件越长压缩越好,如 可以找到和使用更多更长的模式。

问题

为什么我不能利用重复? 1 Mega 是唯一的好处吗?

P.S: 我对 bz2 做了同样的过程,同样的注解【区别只是压缩后的大小本身】 谢谢

【问题讨论】:

    标签: compression


    【解决方案1】:

    这确实是预期的结果。

    确实,zip 压缩算法依赖于在输入中查找重复序列。但是,查找 all 重复在内存和存储方面的计算成本都很高。保持足够的信息来检测 1/4 GB 的重复会非常昂贵,而且我所知道的任何压缩器都无法接近这个大小。

    相反,压缩器在有限大小的滑动窗口内寻找重复。在 zip(和 gzip)的情况下,可以使用命令行参数进行配置,但最大窗口远小于 1 兆字节。 (高度重复的输入,例如只包含零的文件,可以更多地压缩,因为重复序列可以在窗口本身中压缩。但一般来说,这对长重复序列没有帮助。)

    Bzip2 使用不同的策略,但它也需要限制分析输入的大小以避免过多的运行时间。正如bzip2 manual 中所解释的,bzip2 将输入分成块并独立处理每个块。默认(和最大)块大小为 900,000 字节,这将不允许它利用数兆字节的重复序列。

    【讨论】:

    • 非常感谢您的解释。它很有帮助。你有什么想法利用大文件中的重复吗?有什么机制吗?另外,我读到了一些算法,它们将文件集合加入到单个对象中,然后压缩该对象有可能检测文件内部和文件之间的冗余。
    • @anati:那将是tar 实用程序,它确实可以利用文件之间的冗余,但在我描述的相同情况下:何时可以在滑动窗口中检测到冗余。这通常工作得相当好。如果你想压缩 235MB 的重复,恐怕你必须构建自己的工具。
    • 例如,您可以使用 shell 脚本将 gzip 压缩文件解压缩两次。简而言之,如果您对要压缩的数据有所了解,通常可以比通用压缩函数做得更好。
    • 这就是重点。文件中的数据具有标准格式。我认为我应该深入研究压缩,以便定制适合我的数据的算法。但是这里的概述和您的提示对我有很大帮助。谢谢。
    • 7z 允许最大 1 GB 的窗口大小。例如。选项 -md=256m 将是一个足够大的窗口大小来捕获 OP 问题中的重复。
    【解决方案2】:

    具有远距离回溯的压缩器过去仅限于 7z(如 Adler 提到的)和不太知名的压缩器,如 lrzip。但是随着 zstd 成为主流,一个典型的安装可能恰好也有这个功能。

    为了模拟您的大 ASCII 文件,我使用了 enwik8 数据。我运行了以下命令:

    cat enwik8 enwik8 > enwik82
    zstd enwik8
    zstd enwik82
    zstd --long enwik8 -o enwik8.long.zst
    zstd --long enwik82 -o enwik82.long.zst
    

    文件大小为:

    100000000   enwik8
    35633676    enwik8.long.zst
    36445475    enwik8.zip
    35626935    enwik8.zst
    200000000   enwik82
    35644486    enwik82.long.zst
    71251491    enwik82.zst
    

    所以远程匹配成功了! (注意默认--long窗口大小为128M,256M窗口需要--long=28。)

    一些时间信息:

    $ time zstd --long enwik82 -f -o enwik82.long.zst
    enwik82              : 17.82%   (200000000 => 35644486 bytes, enwik82.long.zst) 
    
    real    0m0.911s
    user    0m0.898s
    sys 0m0.130s
    
    $ time zstd enwik82 -f -o enwik82.zst
    enwik82              : 35.63%   (200000000 => 71251491 bytes, enwik82.zst)     
    
    real    0m1.208s
    user    0m1.207s
    sys 0m0.162s
    

    远程匹配显然也使它更快。手册上说它适用于多线程,但我现在懒得测试。

    【讨论】:

      猜你喜欢
      • 2021-09-20
      • 2013-09-03
      • 1970-01-01
      • 2015-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多