5.11 压缩和解压缩
压缩和解压工具是计算机文件管理中的基础工具。数据压缩利用信息的统计冗余性,通过编码算法减少数据表示所需的存储空间。根据是否允许信息丢失,压缩算法可分为无损压缩(lossless compression)和有损压缩(lossy compression)两大类。本节所涉及的工具均采用无损压缩算法,即解压后的数据与原始数据完全一致。
常见的无损压缩算法及其特征如下:
DEFLATE
zip/gzip
LZ77 + Huffman 编码
经典通用
LZMA/LZMA2
xz
LZMA 链式压缩
高压缩率
LZ4
lz4
字节级 LZ77
极高速度
Zstandard
zstd
有限状态熵 + LZ77
兼顾速度与压缩率
bzip2
bz2
Burrows-Wheeler 变换 + Huffman
较高压缩率,速度较慢
zip
zip 格式是 PKZIP 归档格式的实现,其规范由 PKWARE 维护(APPNOTE.TXT),Info-ZIP 项目提供了开源的 zip/unzip 工具实现。zip 是一款压缩和文件打包工具,兼容 PKZIP(Phil Katz 的 ZIP for MSDOS 系统),zip 3.0 版本兼容 PKZIP 2.04 并支持 Zip64 扩展(允许归档和文件超过 2 GB 限制)。zip 使用 deflation 作为默认压缩方法,也可存储不压缩的文件,并自动为每个文件选择更优的方式。
zip 格式是 Windows 上最常用的格式,但对 Unicode 文件名支持有限(取决于 zip 工具版本和压缩设置)。在跨平台交换文件时建议使用 tar.xz 或 tar.zst 格式。
技巧
在使用 zip 压缩中文或非英文字符时出现乱码是正常现象。由于编码方式不同,zip 3.0 在支持 Unicode 的平台上编译时,会额外存储路径的 UTF-8 翻译,以改善跨平台文件名兼容性。解压时可使用
unzip -O选项指定文件名编码(如unzip -O GBK),或使用 convmv 批量转换已解压的乱码文件名。
安装 zip
使用 pkg
# pkg install zip使用 Ports
# cd /usr/ports/archivers/zip/
# make install cleanzip 压缩
zip 解压
zip 文件解压时,需要安装 unzip 工具(FreeBSD 基本系统自带的 bsdunzip 基于 libarchive,功能有限;如需完整功能,可通过 pkg install unzip 安装 Info-ZIP 版本)。
unzip 的 -d 选项后面跟目录名,可以有空格(如 -d /path),也可以紧贴(如 -d/path)。
tar
基本系统自带 tar,无需安装。
tar 是“tape archive”(磁带归档)的缩写,最初用于在磁带上进行文件存储。FreeBSD 的 tar 实现基于 libarchive 库(即 bsdtar),替代了早期版本中的 GNU tar。该实现可从 tar、pax、cpio、zip、jar、ar、xar、rar(包括 RAR2、RAR3 及大部分 RAR5 格式,仅限读取,受专有格式限制)、rpm、7-zip 及 ISO 9660 光盘镜像中提取文件,并可创建 tar、pax、cpio、ar、zip、7-zip 和 shar 格式的归档。
GNU tar 支持自动识别多种压缩格式;bsdtar 在解压时同样会自动检测压缩格式(无需手动指定 -z、-j、-J 等选项),并支持从 tar、pax、cpio、zip 等多种格式中提取,GNU tar 仅支持 tar 相关格式。
思考题
归档文件包是指压缩率为
0的文件集合,即将多个文件或目录打包成单一文件以便存储。单纯使用tar只打包而不压缩。压缩的本质是通过算法减小文件占用的存储空间,而非针对目录本身。因此,常见压缩软件通常先将目录归档为文件,随后再压缩。如何理解归档与压缩的关系?
tar 压缩
tar 解压
选项说明:
x
Extract,解压
v
verbose,输出详细信息模式
f
file,指定文件
C
即 cd,指定路径
xz
基本系统自带 xz、unxz,同样无需安装。xz 格式是当前压缩率最高的格式之一,特别适合大文件归档。
xz 压缩
xz 压缩默认压缩后会删除原文件,建议加 -k 选项保留原文件。
压缩并删除原文件:
unxz 解压
unxz 解压unxz 实际上是 xz 的硬链接,使用 xz -d 或直接 unxz 效果相同。
7z
7z 格式具有极高的压缩率,特别适合大文件归档。
在 FreeBSD 操作系统中,7z 命令可通过安装 archivers/7-zip 包使用。
安装 7-zip
使用 pkg:
通过 Ports:
7z 压缩
a 表示 add,将要压缩的文件添加到 test.7z。
7z 解压
-o 即 Output,指定输出路径。
警告
-o/home/ykla/下载/test中-o与路径之间 不能有空格,这并非拼写错误,而是 7z 命令的设计方式。欢迎提交 PR 改进。
rar
rar 是 Windows 上最流行的格式之一,但在 Unix 世界使用率较低;rar 有较好的恢复记录和分卷功能,适合大文件传输。
rar 格式是专有格式,未在基本系统内置。
安装 rar
通过 pkg 安装:
通过 Ports:
rar 压缩
a 表示 add(添加),将文件添加到 archive.rar。
rar 解压
zstd
zstd 是 Meta(原 Facebook)开发的快速压缩算法,兼顾压缩速度和压缩率,是现代系统首选的压缩格式。
zstd 也是基本系统内置的压缩工具,zstd 支持多种预设级别,从最快(-1)到极限压缩(--ultra -22)。
zstd 压缩
使用 zstd 压缩单个文件
使用 zstd 压缩文件夹。
zstd 不直接支持压缩文件夹(参见:GitHub. How can I compress a directory?[EB/OL]. [2026-03-26]. https://github.com/facebook/zstd/issues/1526.)。该 Issue 讨论了 zstd 不支持直接压缩目录的技术原因与替代方案,因此需要先将文件夹打包为 tar 文件。
思考题
zstd 为什么不支持压缩文件夹?有哪些可能性?
将 test.tar 压缩成 test.tar.zst
此外,也可直接使用 tar 的 --zstd 选项一步完成打包与压缩:
示例:
查看结果:
文件结构图:
zstd 解压
解压到当前路径
技巧
这样解压出来的是
test.tar,还需要再用tar解压一次。
解压到指定路径
技巧
同上,解压出来的是
test.tar,还需要再用tar解压一次。
课后习题
使用 zip、tar、xz、7z、rar、zstd 等工具分别压缩和解压包含中文文件名的文件,对比各工具对 UTF-8 编码的处理方式,分析不同压缩格式在国际化支持上的设计差异。
使用不同压缩算法(gzip、bzip2、xz、zstd)压缩同一组文件,对比压缩率、压缩时间和解压时间,分析各算法在压缩效率与计算性能之间的权衡策略。
查阅 zip 格式规范中关于文件名编码的条款,分析中文文件名乱码问题的根源,评估现有补丁方案的适用范围。
最后更新于