美文网首页游戏开发我用 Linux技术文
Linux下的文件打包和压缩

Linux下的文件打包和压缩

作者: davidpp | 来源:发表于2016-11-15 18:58 被阅读3090次

为什么要整理一下Linux下的打包和压缩工具呢?原因很简单,因为遇到问题了:游戏服务器可执行文件、配置和各种资源文件有4G多,每次在做版本的时候,编译完打包压缩要用掉10分钟多。我在上篇C++构建系统选择里面有提到过,200万行的代码编译用时不到10分钟,而现在一个简单的打包压缩竟然占用了10分钟,虽说这个步骤日常开发过程中很少操作,但每次凌晨做版本的时候,由于需求的变更,需要不断地构建、打包、压缩。做版本的同学苦不堪言,所有开发人员也得等着,这样浪费大家宝贵的时间是极度可耻的!遇到问题就要解决问题,问题解决了如果不记下来,下次遇到了又得去折腾了。下面进入正题。

虽说打包和压缩的原因各种各样,最重要的目的就是:减少文件的体积,从而节约磁盘空间和网络带宽。压缩文件的时候,最注重两个因素:速度压缩比。慢如蜗牛还是快如闪电?当然选择越快越好、压缩比越高越好。但是鱼与熊掌不可兼得,往往压缩比高的算法,需要的计算量就比较大,花费的时间就比较多。有没有加速的办法呢?

下面我会介绍一下我所熟知的Linux下的打包压缩工具,并做下对比,给出建议。上面遇到的问题,最后也会给出解决方法。

Linux下的文件压缩命令

打包和压缩工具概览

打包命令

Linux下的打包命令是tar,意思是:Tape Archiver。在计算机远古时代,打包后的文件会写到磁带(Tape)里面,所以才有了tar。而打包往往伴随着压缩,于是tar命令本身也支持多种压缩方式。

Linux下还有一个与此非常相似的命令ar,意思是:Archive。同为打包有啥区别了?
一般ar是用来打包目标文件生成静态库.a文件的,基本上不会用于普通文件的打包。

压缩命令

下面会对Linux下常见的压缩命令:zip, gzip, bzip2, xz, 7za进行对比。结果如下表:

命令 发布时间 压缩算法 压缩用时 解压用时 压缩后的大小
zip 1990 DEFLATE 2m43s 2m15s 796MB
gzip 1993 DEFLATE 2m34s 32s 796MB
bzip2 1996 Burrows-Wheeler 9m20s 2m1s 660MB
xz 2009 LZMA,LZMA2 28m31s 1m3s 474MB
7za 1999 LZMA,LZMA2 1m51s 52S 487MB

数据测试文件game.tar,大小为4G左右。下面为测试脚本:

tarfile=game.tar

echo "-------zip"
time zip $tarfile.zip $tarfile;
rm $tarfile
ls -lh $tarfile.zip
time unzip $tarfile.zip

echo "--------gzip"
time gzip $tarfile
ls -lh $tarfile.gz
time gzip -d $tarfile.gz

echo "--------bzip2"
time bzip2 $tarfile
ls -lh $tarfile.bz2
time bzip2 -d $tarfile.bz2

echo "--------xz"
time xz $tarfile
ls -lh $tarfile.xz
time xz -d $tarfile.xz

echo "--------7za"
time 7za a $tarfile.7z $tarfile
rm $tarfile
ls -lh $tarfile.7z
time 7za e $tarfile.7z

"压缩用时"、"解压用时"和"压缩后的大小"是用game.tar进行测试的。测试的机器CPU是32核,型号为:Intel(R) Xeon(R) CPU E5-2670 @ 2.60GHz

文件压缩

gzip

官方首页:http://www.gzip.org/

gzip, GNU的zip,是Linux的经典压缩工具,压缩后的文件后缀是.gz。采用的算法也是DEFLATE,该算法广泛应用于PNG图像、HTTP协议、SSH等。最大的优势就是速度快,压缩比还不错,几乎所有Linux系统都有安装gzip。

gzip压缩后的文件大小和.zip也差不多,压缩时间和zip相差不大,但解压缩的速度要明显高于zip。在Linux一般通过tar调用,很少直接使用。

压缩:

gzip game.tar   # 压缩文件
gzip -r  dir   # 目录下的所有文件进行递归压缩(目录下的所有文件都会生成.gz文件)

解压缩:

gzip -d game.tar.gz

bzip2

官方首页: http://www.bzip.org/

bzip2也是Linux系统常见的压缩方式,压缩后的文件后缀为.bz2。bzip2,基于Burrows–Wheeler algorithm,可以将文件压缩至10%-15%,解压用时比压缩用时快2-6倍。

gzip和bzip2实现算法不同,决定了它们各有优缺点:bzip2有比较高的压缩比,相应的压缩用时也要久一些,占用的系统内存也更大;gzip最大的优势就是压缩解压速度快,压缩比稍逊于bzip2。

压缩:

bzip2 file

解压缩:

bzip2 -d file.bz2

xz

官方首页:http://tukaani.org/xz/

xz是一个相对新的压缩命令,第一版是2009年发出来的。使用了LZMA2算法,该算法有这比高的压缩比,特别适用于对存储或带宽有严格要求的场景下,为了高的压缩比,压缩时间也是大大增加。

xz对压缩比和用时也提供了权衡的选项:

-0 ... -9 压缩预设,默认为6。
-e, --extreme 使用更多的CPU时间提高压缩比

压缩:

xz file

解压缩:

xz -d file.xz

PS. 使用xz时,要注意有些旧版本的Linux操作系统本身不支持,需要安装后才能使用。

zip

官方首页:http://www.info-zip.org/mans/zip.html

zip用于压缩,unzip用于解压缩,生成的文件格式是.zip。非常古老的压缩方式,压缩比比较低,好处就是由于古老,所以基本上是个操作系统都会默认对此进行支持。

虽然zip和gzip使用的算法都是基于DEFLATE,但具体文件格式是不一样的,所以.zip.gz文件是不兼容的。zip很少在Linux下使用,Linux下直接用gzip即可,多数情况都是其他平台下生成的.zip在Linux系统下面解压一下。

zip、7z和gzip、bzip2、xz还有一点不同的是,zip和7z本身支持打包,其他压缩命令仅是单纯的对单个文件或文件夹递归进行压缩。

压缩:

zip squash.zip file1 file2 file3  # 压缩文件
zip -r squash.zip dir1              # 目录打包并压缩

解压缩:

unzip squash.zip

7z

官方首页:http://www.7-zip.org/

7-Zip是一个有着高压缩比的打包压缩工具,提供了多平台(如:Windows、Mac、Linux等)支持,高压缩比也是得益于LZMA和LZMA2算法。上面的测试可以看出,7z和xz都是基于LZMA算法,但时间却天地之差,为何?答案是:7z是多线程的,压缩和解压并行计算。测试用的机器是32核的,在使用7z压缩解压时,CPU利用率达到3000%左右。

p7zip是Linux/Unix下7-ZIP的命令行版,命令是7za。7-ZIP并不是单纯的压缩工具,它支持多种压缩格式,在Windows/Mac有界面的系统下还有相应的GUI文件管理器工具支持。

7-ZIP的主要特点:

  • High compression ratio in 7z format with LZMA and LZMA2 compression
    Supported formats:
  • Packing
    • unpacking: 7z, XZ, BZIP2, GZIP, TAR, ZIP and WIM
      -Unpacking only: AR, ARJ, CAB, CHM, CPIO, CramFS, DMG, EXT, FAT, GPT, HFS, IHEX, ISO, LZH, LZMA, MBR, MSI, NSIS, NTFS, QCOW2, RAR, RPM, SquashFS, UDF, UEFI, VDI, VHD, VMDK, WIM, XAR and Z.
  • For ZIP and GZIP formats, 7-Zip provides a compression ratio that is 2-10 % better than
  • the ratio provided by PKZip and WinZip
  • Strong AES-256 encryption in 7z and ZIP formats
  • Self-extracting capability for 7z format
  • Integration with Windows Shell
  • Powerful File Manager
  • Powerful command line version
  • Plugin for FAR Manager
  • Localizations for 87 languages

压缩:

7za a  game.7z  gamedir

解压:

7za e game.7z

PS. 大多Linux下都没有安装7z,需要手动安装。

并行压缩和解压缩

压缩比和执行速度,鱼与熊掌两者兼得,如何做呢?上面也看到了7z利用多线程,执行LZMA算法也是很快就完成的。

开篇提到的问题是否也可以利用并行解决呢?由于各种原因,打包格式只能以.bz2的形式发布到运维系统,而bzip2的压缩速度实在是不敢恭维。bzip2的压缩过程是否可以并行执行?它的算法和文件格式支持的并行的话还好,不然也就没辙了,Google了一把,大神们已经准备了pbzip2,测试了一下,几乎被惊呆了:10min一下子只需要50s(32核E5处理器,4G文件大小)。

下面整理一下gzip、bzip2和xz及其并行版本的对比:

普通 vs. 并行 压缩用时 解压用时
gzip vs. pigz 2m34s vs. 0m11s 0m32s vs. 0m13s
bzip2 vs. pbzip2 9m20s vs. 0m40s 2m01s vs. 0m12s
xz vs. pixz 28m31s vs. 1m30s 1m03s vs. 0m6s

pigz

官方首页:http://zlib.net/pigz/

PIGZ – pigz,并行版本的gzip的实现 (Parallel Implementation of GZip),利用多线程来执行压缩,生成的文件和gzip完全兼容。解压缩的算法不可以并行化,为了加速,pigz在解压缩的时候创建了3个线程,主线程负责执行解压缩,其他的负责读写和检查计算,所以 解压缩速度比gzip也要快一些。

输入文件被划分成128KB大小的块并行执行压缩算法,然后按照顺序写到输出文件里,默认的块大小是128KB,也可以通过-b选项指定大小。执行压缩的线程数量,默认是机器中所有的CPU核心数量,也可以通过-p指定压缩线程的数量。

压缩:

pigz game.tar
```0

解压缩:

``` bash
pigz -d game.tar.gz

pbzip2

官方首页:http://compression.ca/pbzip2/

PBZIP2 – pbzip2,并行版本的bzip2的实现(Parallel implementation of the BZIP2),多线程压缩和解压缩,生成的文件和bzip2兼容,也即是说使用pbzip2生成的bz2文件,可以使用bzip2进行解压缩,反之亦可。pbzip2的解压过程也是多线程执行的,所以它的解压速度要快于pgiz。

块大小可以通过-1 .. -9-b#来指定,数字分别代表100k .. 900k(默认900k);线程数量可以通过-p#来指定,默认为机器中所有CPU核心。

压缩:

pbzip2 game.tar

解压缩:

pbzip2 game.tar.bz2

pixz

官方首页:https://github.com/vasi/pixz

pixz,xz的并行和带索引版(Parallel Indexing xz)。xz生成的.xz文件生成一大块压缩后的数据,pixz则生成一系列压缩后的可以随机访问的小块集合。pixz这种索引功能对于特别大的tarball文件特别有用,这样从压缩后的文件里面解压部分文件成为可能。比如在备份数据时候,可能10个G的压缩包,但当你使用此包时,仅需要其中的一个文件,xz则需要把10个G解压后取自己想要的文件,而pixz则直接可以指定解压需要的文件,没必要浪费磁盘和CPU。不过要使用索引功能的话,生成的文件后缀为.tpxz.xz不兼容的。

pixz和xz完全兼容,pixz的功能是xz的超集。听起来很不错吧!一般系统都不会安装此工具,源码安装时候依赖的包也有好几个:

  • pthreads
  • liblzma
  • libarchive
  • AsciilDoc

压缩:

pixz game.tar game.tar.xz   # 生成与xz兼容的格式
pixz game.tar           # 生成后缀为tpxz的格式,与xz不兼容

解压缩:

pixz -d game.tar.xz
pixz -d game.tar.tpxz

使用tar进行打包和压缩

上面所提到的压缩命令,gzip、bzip2、xz或并行版本的pigz、pbzip2、pigxz一般很少单独使用,多数时候都是在tar命令打包后执行压缩,合着tar一起使用。

tar本身支持的选项(xz老版本的tar可能不支持,需要更新哦!):

# 仅打包
tar cf  game.tar game-dir
tar xf  game.tar

# 打包后使用gzip进行压缩
tar cfz game.tar.gz game-dir
tar xfz game.tar.gz

# 打包后使用bzip2进行压缩
tar cfj game.tar.bz2 game-dir
tar xfj game.tar.bz2

# 打包后使用xz进行压缩
tar cfJ game.tar.xz game-dir
tar xfJ game.tar.xz

tar指定压缩工具(命令必须支持-d选项为解压):

# 打包后使用并行版本的gzip
tar -Ipigz -cf game.tar.gz game-dir
tar -Ipigz -xf game.tar.gz

# 打包后使用并行版本的bzip2
tar -Ipbzip2 -cf game.tar.bz2 game-dir
tar -Ipbzip2 -xf game.tar.bz2

# 打包后使用并行版的xz
tar -Ipixz -cf game.tar.xz game-dir
tar -Ipixz -xf game.tar.xz

压缩算法

关于压缩的工具,可谓五花八门。万变不离其宗,上面提到的工具用到的算法如下:

压缩算法涉及到一些数据知识和编码学,这里就不详细介绍了,有兴趣的同学自行Google。

小结

本文介绍了Linux下的常用的打包压缩工具:tar、gzip、bzip2、xz及其并行版本的基本用法,还有常用的zip7-ZIP的命令行版的基本用法,并逐个进行测试对比。

在Linux下面对于压缩格式的选择,我的建议是:

  • 临时性的压缩包尽量选择压缩速度快的格式,如:.gz。用于持久备份或存档的文件,尽量选择压缩比较大的格式,如:.bz2.xz
  • 大文件压缩时,尽量控制在5min以内,否则请尝试使用并行版本或将文件拆分为多份。
  • 尽量使用常见的压缩命令。7z虽然好处多多,Linux较少使用(记得Unix命令的设计哲学:只干一件事,把它做到极致,7z功能太多了)

参考资料

相关文章

  • Linux 压缩与解压缩

    在 Linux 中,文件压缩的过程: 待压缩的多个文件 >> 打包成单个文件 >> 文件压缩。 Linux 中常见...

  • Linux下打包压缩war、解压war包和jar命令

    问题 Linux下打包压缩war、解压war包和jar命令 解决 把project_a文件夹下的文件打包成proj...

  • Linux下的文件打包和压缩

    为什么要整理一下Linux下的打包和压缩工具呢?原因很简单,因为遇到问题了:游戏服务器可执行文件、配置和各种资源文...

  • Linux 基础

    了解 Linux 的常用命令 远程登录 上传下载 系统目录 文件和目录操作 Linux 下的权限体系 压缩和打包 ...

  • 新手必须掌握的Linux命令---打包压缩与搜索命令

    [TOC] 新手必须掌握的Linux命令---打包压缩与搜索命令 在Linux系统中对文件进行打包压缩与解压,以及...

  • 文件打包与压缩(第6节)

    “Linux 基础入门(新版)”实验报告 文件打包与解压缩 文件打包与压缩(主要zip、rar、tar) 二。概念...

  • 文件打包与解压缩

    在学习Linux上的文件打包与解压缩之前,有必要学习一下常见的文件打包格式。Windows上常见的文件打包格式有z...

  • Linux 学习2

    Linux继续学习 1、打包、压缩管理 gzip 文件名 压缩文件 gzip -d 解压文件压缩包 tar -cz...

  • linuxs压缩打包文件命令

    原文:github上的总结 压缩文件的操作命令 1)打包并压缩文件: Linux中的打包文件一般是以.tar结尾的...

  • linux命令

    文件搜索 打包和压缩文件 Linux下的多用户多任务操作系统 查看文件内容 挂载一个文件系统 磁盘空间 用户和群组...

网友评论

    本文标题:Linux下的文件打包和压缩

    本文链接:https://www.haomeiwen.com/subject/ptdlpttx.html