公开压缩算法概述

0 序

文由

  • 下载开源软件时,源站经常会提供多种格式的下载文件如zip、tar.gz等。如果是Linux操作系统,我们一般会下意识地选择tar.gz格式的压缩文件;而对于Windows操作系统,我们常选择zip格式。我一直以来就是这么用的,也没有深入了解过,直到最近项目上某需求,需在节省网络流量、压缩效率等因素下选型【压缩算法】,才开始深入思考这一话题。

  • 对于刚接触Linux的人来说,一定会给Linux下一大堆各式各样的文件名给搞晕。别个不说,单单就压缩文件为例,我们知道在Windows下最常见的压缩文件就只有2种:ziprar。可是Linux就不同了,它有:.gz.tar.gztgzbz2.Z.tar等众多的压缩文件名。此外Windows下的.zip.rar也可在Linux下使用,不过在Linux使用.zip.rar的人就太少了。本文就来对这些 常见的压缩文件进行一番小结。

实验数据集

  • 本篇全文采用本数据集(以下简称:样例数据集)进行实验。
  • 便于涵盖和测试不同种类数据情况,分别提供了一些二进制流式数据、字符串数据。

.bin文件 : 二进制流数据
.hex-bin文件、.json文件 : 字符串数据

total 4006
drwxr-xr-x 1 USER001 1049089      0 May 11 09:55 ./
drwxr-xr-x 1 USER001 1049089      0 Apr 29 20:28 ../
-rw-r--r-- 1 USER001 1049089    322 Apr 29 13:52 1714369932783-20240429135212.bin
-rw-r--r-- 1 USER001 1049089    644 Apr 29 13:52 1714369932783-20240429135212.hex-bin
-rw-r--r-- 1 USER001 1049089 402489 Apr 29 13:53 1714369932783-20240429135212.json
-rw-r--r-- 1 USER001 1049089    332 Apr 29 13:52 1714369942814-20240429135222.bin
-rw-r--r-- 1 USER001 1049089    664 Apr 29 13:52 1714369942814-20240429135222.hex-bin
-rw-r--r-- 1 USER001 1049089 432748 Apr 29 13:53 1714369942814-20240429135222.json
-rw-r--r-- 1 USER001 1049089    325 Apr 29 13:52 1714369952807-20240429135232.bin
-rw-r--r-- 1 USER001 1049089    650 Apr 29 13:52 1714369952807-20240429135232.hex-bin
-rw-r--r-- 1 USER001 1049089 402489 Apr 29 13:53 1714369952807-20240429135232.json
-rw-r--r-- 1 USER001 1049089    321 Apr 29 13:52 1714369962871-20240429135242.bin
-rw-r--r-- 1 USER001 1049089    642 Apr 29 13:52 1714369962871-20240429135242.hex-bin
-rw-r--r-- 1 USER001 1049089 402489 Apr 29 13:54 1714369962871-20240429135242.json
-rw-r--r-- 1 USER001 1049089    331 Apr 29 13:52 1714369972897-20240429135252.bin
-rw-r--r-- 1 USER001 1049089    662 Apr 29 13:52 1714369972897-20240429135252.hex-bin
-rw-r--r-- 1 USER001 1049089 432748 Apr 29 13:54 1714369972897-20240429135252.json
-rw-r--r-- 1 USER001 1049089    325 Apr 29 13:53 1714369982887-20240429135302.bin
-rw-r--r-- 1 USER001 1049089    650 Apr 29 13:53 1714369982887-20240429135302.hex-bin
-rw-r--r-- 1 USER001 1049089 402489 Apr 29 13:54 1714369982887-20240429135302.json
  • 共计18个文件、原始大小 2.36 MB(248 1320 byte = 2423.16KB)、占用空间 2.39MB(251 4944 byte = 2456KB)

实验环境

  • OS : Windows 10 (64bit)
  • CPU : 11th Gen Intel(R) Core(TM) i7-1165G7 @ 2.80GHz 1.69 GHz
  • Memory : 16.0 GB (15.7 GB 可用)
  • Shell Tool : Git Command Shell

算法/工具/程序、格式

  • 压缩算法 := 对原始数据进行存储空间压缩的步骤/方法。
  • 压缩程序 := 压缩工具 := 基于某一具体【压缩算法】编程实现的软件 ∈ { zip , gzip 等压缩程序 }
  • 压缩格式 := 不同压缩程序支持专有的、不同的压缩算法。文件格式提现在文件名称中,只是为了便于的阅读。原则上,不建议随意更改文件名的后缀格式,否则用户不知道该使用哪种解压程序对目标压缩文件进行文件解压和数据读取。

1 基础概念篇

1.1 为什么要有压缩文件?

多文件【打包归档】场景

  • 文件对于操作系统的重要性不言而喻————Unix/Linux更是基于文件管理的操作系统。当然,深入理解文件系统不是本文的重点。
  • 我们来想一下普通用户都会用到的场景,假设你需要往U盘里拷贝100个Excel文件,我们当然可以Ctrl+A全选、Ctrl+C复制最后到U盘中Ctrl+V粘贴,一顿操作猛如虎。
  • 但若想把这100个文件通过QQ发送给你的朋友,你若图省事儿一股脑全拖到聊天窗口发送给你的朋友,估计网线那头的朋友会抓狂——他需要一个个的接收、另存… …
  • 那么问题来了————有没有一种简单有效的方法来进行文件传输?
  • 答案是肯定的,那就是:打包它!划重点:不是压缩

打包与压缩

  • 在具体总结各类压缩文件压缩算法之前,首先要弄清2个概念:打包压缩。为什么要区分这两个概念呢?其实这源于Linux中的很多【压缩程序只能针对一个文件进行压缩。当你想要压缩一大堆文件时,你就得先借助另它的工具将这一大堆文件先打成一个包,然后再就原来的压缩程序进行压缩。

【实验(001)】错误示范:基于gzip程序,压缩样例数据集的多个文件————实际无法完成多文件的压缩

# 1 尝试压缩文件夹下多个文件为1个文件
$ gzip -c ./* > test-001.gz

# 2 查看压缩文件的大小 : 116360 byte ≈ 113.63 KB
$ ls -la test-001.gz
-rw-r--r-- 1 USER001 1049089 116360 May 11 10:06 test-001.gz

# 3 查看压缩文件内的文件内容 (不解压)
$ gunzip -c test-001.gz | less -R
注:可看到不止1个被压缩文件的内容

# 4 查看压缩文件内是否有多个被压缩文件 : 仅1个被压缩文件 (与3的现象矛盾,说明这种多文件的gzip压缩方式是有问题的)

仅看到有1个被压缩文件: 1714369932783-20240429135212.bin

【实验(002)】如果要利用gzip压缩多个文件,则需:

$ gzip file1.txt file2.txt file3.txt

这将分别生成file1.txt.gzfile2.txt.gzfile3.txt.gz等多个.gz压缩文件。

上述2个实验能直接证明:没有打包程序的支持时,Linux的【压缩程序(gzip)只能针对一个文件进行压缩

概念:打包

打包是指将一大堆文件或目录什么的变成一个总的文件。tar、zip都有打包功能。不改变文件大小,就是打个包,变成一个文件的文件夹,解压速率也很快。

概念:压缩

压缩是将一个大的文件通过一些压缩算法变成一个小文件,顾名思义,通常说的rar、tar等这些大多都是格式,而不是算法。

1.2 常见打包工具

rar / tar / zip / 7z 均是归档容器,其内可放多个文件、有目录结构。
其中,zip是不识别文件名的编码,rar是带单独的压缩算法(据说是类 Deflate算法)

tar

  • tar本身是一个文件打包备份的工具,没有自身的压缩功能。通常的使用方式为打包后再调用其他压缩库进行文件压缩。比较适合Linux系统,保持文件权限状态、软硬链接能力强。

zip

rar

7z

1.2 常见压缩算法

  • zip是公开的、免费的一种打包算法、压缩算法。但压缩比目前相对不太高。

  • gz,gzip是GNU组织开发的一个压缩程序,.gz结尾的文件就是gzip压缩的结果。与gzip相对的解压程序是gunzip。tar中使用-z这个参数来调用gzip。

  • rar是带专利的商业算法,压缩比目前比较高。

  • bz2是Linux下常见的压缩文件格式,是由具有高压缩率的压缩工具bzip2生成,以后缀为.bz2结尾的压缩文件。tar中使用-j这个参数来调用bzip2。

  • Z,compress也是一个压缩程序,但是好象使用compress的人不如gzip和bzip2的人多。.Z结尾的文件就是bzip2压缩的结果。与 compress相对的解压程序是uncompress。tar中使用-Z这个参数来调用compress。

# 压缩
compress FileName

# 解压
uncompress FileName.Z

==========

# 解压(结合打包工具TAR)
tar Zxvf FileName.tar.Z

# 压缩(结合打包工具TAR)
tar Zcvf FileName.tar.Z DirName

2 性能对比【待续】

打包/压缩算法 原始文件(集)大小(unit:byte) 打包文件/压缩文件大小(unit:byte) 文件格式 压缩率(%) 压缩耗时(ms) 解压耗时(ms) 压缩/打包的命令&参数
tar 2481320 2498560 .tar tar -cvf test.tar ./compress/ / tar -xvf test.tar
zip 2481320 120874 .zip 120874/2481320=4.87% 1318 6773 zip -r test.zip ./compress/
rar 2481320 .rar
7z 2481320 .7z
gzip 2481320 .gz
lz4 2481320
snappy 2481320
zstd 2481320
bz2 2481320
Z 2481320 .Z
tar+gz 2481320 118845 .tar.gz 118845/2481320=4.79% 1253 7634 tar -czvf test.tar.gz ./compress/*

压缩耗时、解压耗时 : 试验10次,取平均值

X 参考文献

posted @ 2024-05-11 11:14  千千寰宇  阅读(4)  评论(0编辑  收藏  举报