tar、gzip、zip、jar是什麼,怎麼查看?

原創:扣釘日記(微信公眾號ID:codelogs),歡迎分享,轉載請保留出處。

簡介

如果你是後端程序員,我想你一定見過*.tar.gz*.zip*.jar後綴的文件吧,這些都是壓縮文件,那這些文件都是怎麼生成的,又有哪些關鍵區別呢?本文將帶你一起了解這些文件和配套的操作命令,以及其經常使用的場景。

tar與gzip

Linux上最常見的壓縮文件就是*.tar.gz了,各種開源軟件常以這種格式發佈源碼或程序,所以作為一名後端開發,還是很有必要了解一下的。

首先,可以發現這個文件後綴名有兩段,即.tar.gz,取這個名稱也是有原因的,因為它的製作過程就分為兩個部分,如下:

  1. 使用tar將目錄打包成單個.tar文件
# 將applogs目錄打包為applogs.tar文件
# 其中-c代表打包、-f指定打包文件名
$ tar -cf applogs.tar applogs/

# 可以發現,打包文件大小與目錄佔用大小差不多,因為tar僅僅是把目錄中文件拼成單個文件,默認並不壓縮  
$ du -sh applogs/ applogs.tar
177M    applogs/
175M    applogs.tar
  1. 使用gzip將.tar文件壓縮為.gz文件
# 使用gzip壓縮,會生成applogs.tar.gz文件
$ gzip -k applogs.tar

# 可以發現壓縮後文件體積明顯變小
$ du -sh applogs.tar applogs.tar.gz
175M    applogs.tar
8.8M    applogs.tar.gz

這就是*.tar.gz文件的製作過程,其實這兩步使用tar命令可以簡化為一步,如下:

# 打包並壓縮,其中-z代表打包後再使用gzip壓縮
$ tar -czf applogs.tar.gz applogs/

# 解壓到當前目錄
$ tar -xzf applogs.tar.gz -C ./

壓縮日誌文件
另外,由於日誌文件內容一般都有很高重複率,這導致Linux上經常會將後端系統產生的歷史日誌文件壓縮後存儲起來,這樣可以大幅減低磁盤空間佔用。

基於這種情況,Linux上又誕生了一批查看壓縮日誌文件的命令,如zcat、zgrep、zless等,如下:

# 自動解壓文件,並將其中文件內容輸出
$ zcat applogs.tar.gz

# 自動解壓文件,並在其中搜索,用法和grep類似
$ zgrep -a 'error' applogs.tar.gz

這比傻乎乎地先解壓文件,再在文件中搜索要高效多了。

tar與其它壓縮算法
另外,除了gzip外,tar其實也可以搭配其它壓縮算法,像bzip2、xz等等,如下:

  -j, --bzip2                filter the archive through bzip2
  -J, --xz                   filter the archive through xz
      --lzip                 filter the archive through lzip
      --lzma                 filter the archive through xz
      --lzop                 filter the archive through lzop
  -z, --gzip, --gunzip, --ungzip   filter the archive through gzip
      --zstd                 filter the archive through zstd
  -Z, --compress, --uncompress   filter the archive through compress

zip與jar

zip同樣是一種常見的壓縮文件格式,後綴是*.zip,與上面tar、gzip不同的是,zip將打包與壓縮兩個過程融合在一起了,在Linux下對應的操作命令是zipunzip,如下:

# 創建zip壓縮文件
$ zip -r applogs.zip applogs/

# 查看zip壓縮文件中有哪些文件
$ unzip -l applogs.zip
Archive:  applogs.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  2022-09-17 12:58   applogs/
    99166  2022-09-16 18:20   applogs/demo.2022-09-16.0.log
 13177092  2022-09-17 13:37   applogs/demo.2022-09-17.0.log
      948  2022-08-09 15:08   applogs/demo.log
...
---------                     -------
203039002                     140 files

# 解壓zip文件,-d指定解壓目錄
$ unzip applogs.zip -d ./

與gzip類似的是,zip也配套了一批方便特定場景使用的命令工具,如zipinfo、zipgrep等,如下:

# zipinfo查看zip文件包含哪些文件
$ zipinfo applogs.zip
Archive:  applogs.zip
Zip file size: 9573195 bytes, number of entries: 140
drwxrwxrwx  3.0 unx        0 bx stor 22-Sep-17 12:58 applogs/
-rwxrwxrwx  3.0 unx    99166 tx defN 22-Sep-16 18:20 applogs/demo.2022-09-16.0.log
-rwxrwxrwx  3.0 unx 13177092 tx defN 22-Sep-17 13:37 applogs/demo.2022-09-17.0.log
-rwxrwxrwx  3.0 unx      948 tx defN 22-Aug-09 15:08 applogs/demo.log
...
140 files, 203039002 bytes uncompressed, 9546235 bytes compressed:  95.3%

# zipgrep自動解壓文件,並在其中搜索,用法和grep類似
$ zipgrep 'error' applogs.zip

查看jar文件
目前,絕大多數java項目都是基於spingboot的,眾所周知,spingboot會將項目打包成單個jar文件來部署,但其實jar文件本質上就是zip格式,它相比zip文件只是多了一個META-INF/MANIFEST.MF文件而已,如下:

$ unzip -p app.jar META-INF/MANIFEST.MF
Manifest-Version: 1.0
Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx
Implementation-Version: 0.0.1-SNAPSHOT
Spring-Boot-Layers-Index: BOOT-INF/layers.idx
Start-Class: com.example.demo.DemoApplication
Spring-Boot-Classes: BOOT-INF/classes/
Spring-Boot-Lib: BOOT-INF/lib/
Build-Jdk-Spec: 1.8
Spring-Boot-Version: 2.4.0
Created-By: Maven Jar Plugin 3.2.0
Main-Class: org.springframework.boot.loader.JarLauncher

如上所示,MANIFEST.MF文件指定了jar包的Main-Class,這樣當執行java -jar app.jar時,java就知道去哪個類找main方法了,而spingboot打包的jar,無非就是將啟動類換成了自己的而已。

而很多時候,我們需要確認下jar文件裏面的內容,比如我想看一下app.jar里被spingboot內嵌的tomcat的線程池配置大小,可如下查看:

$ zipgrep 'max-thread' app.jar 
BOOT-INF/classes/application.yml:    max-threads: 500

這可比jdk自帶的jar命令方便多了,如果你是java開發同學,這個命令應該成為你開發工具箱中的一員。

總結

ok,壓縮文件與命令介紹得差不多了,簡單總結一下:

  1. tar、gzip:用於打包或解壓*.tar.gz文件的命令,雖然它們是兩個命令,但幾乎都是一起使用的。
  2. zip、unzip:用於打包或解壓*.zip文件的命令,值得注意的是,它們同樣可處理*.jar文件,且在搜索場景中,使用zipgrep更方便。

less命令其實可以直接打開這些壓縮文件,它甚至可以打開png、pdf等廣義上的壓縮文件!

另外,Linux平台上其實還有一些其它的壓縮命令,如bzip2、xz、7z、rar等,就不一一介紹了,感興趣可查看Linux man文檔。

往期內容

密碼學入門
接口偶爾超時,竟又是JVM停頓的鍋!
耗時幾個月,終於找到了JVM停頓十幾秒的原因
mysql的timestamp會存在時區問題?
真正理解可重複讀事務隔離級別
字符編碼解惑