bet*_*eta 4 compression stream xz bzip2
我最近备份了我即将过期的大学主目录,将其作为 tar 流发送并在我的端进行压缩:ssh user@host "tar cf - my_dir/" | bzip2 > uni_backup.tar.bz2.
这让我思考:我只知道压缩如何工作的基础知识,但我想这种压缩数据流的能力会导致较差的压缩,因为算法需要在某个时刻完成处理数据块,写下这个到输出流并继续下一个块。
\n\n是这样吗?或者这些程序只是将大量数据读入内存,压缩它,写入它,然后再重复一遍?或者这些 \xe2\x80\x9cstream 压缩器\xe2\x80\x9d 中是否使用了任何巧妙的技巧?我看到bzip2和xz的手册页都讨论了内存使用情况,并且man bzip2还暗示了这样一个事实:将要压缩的数据切割成块时几乎不会丢失:
\n\n\n\n\n较大的区块大小会导致边际收益迅速递减。大多数压缩来自块大小的前两三百 k,在小型机器上使用 bzip2 时值得记住这一事实。同样重要的是要认识到,解压缩内存要求是在压缩时通过选择块大小来设置的。
\n
我仍然很想知道是否使用了其他技巧,或者我可以在哪里阅读更多相关内容。
\n这个问题更多地与缓冲区处理相关,而不是与压缩算法相关,尽管也可以对此进行一些说明。
一些压缩算法本质上是“基于块的”,这意味着它们绝对需要使用特定大小的块。这是 bzip2 的情况,它的块大小是通过“级别”开关选择的,从 100kb 到 900kb。因此,如果您将数据流式传输到其中,它将等待该块被填充,并在该块已满时开始压缩该块(或者,对于最后一个块,它将以其接收到的任何大小进行工作)。
其他一些压缩算法可以处理流,这意味着它们可以使用内存缓冲区中保存的旧数据连续压缩新数据。基于“滑动窗口”的算法可以做到这一点,通常 zlib 能够实现这一点。
现在,即使是“滑动窗口”压缩器也可能选择将输入数据切割成块,以便更轻松地进行缓冲区管理,或者开发多线程功能,例如 Pigz。