文件壓縮
通常壓縮技術都是應用在減少文件大小上。比如微信傳給好友文件時,文件大小上限100M,此時需要傳的文件卻是110M,但是經過壓縮技術,110M的文件可能壓縮成<=100M,好友接收后解壓縮文件就可恢復到原本的大小110M。
因為這些比較大型的文件透過所謂的文件壓縮技術之后,可以將他的磁碟使用量降低, 可以達到減低文件容量的效果,此外,有的壓縮程序還可以進行容量限制, 使一個大型文件可以分割成為數個小型文件,以方便軟盤片攜帶。
文件壓縮原理
那么什么是文件壓縮原理?目前我們使用的計算機系統中都是使用所謂的 **byte **單位來計量的!不過,事實上,計算機最小的計量單位應該是 **bit **才對啊,此外,我們也知道 1 byte = 8 bit 。但是如果今天我們只是保存一個數字,亦即是 1 這個數字呢?磁盤會如何記錄?假設一個 byte 可以看成底下的模樣:
由於我們記錄數字是 1 ,考慮計算機所謂的二進位喔,如此一來, 1 會在最右邊占據 1 個 bit ,而其他的 7 個 bit 將會自動的被填上 0 !你看看,其實在這樣的例子中,那 7 個 bits應該是空的才對!不過,為了要滿足目前我們的操作系統數據的存取規范,所以就會將該數據轉為 byte 的型態來記錄了!而一些聰明的計算機工程師就利用一些復雜的計算方式, 將這些沒有使用到的空間丟出來,以讓文件占用的空間變小!這就是壓縮的技術!
另外一種壓縮技術也很有趣,是將重復的數據進行統計記錄的。舉例來說,如果你的數據為『111....』共有100個1時, 那么壓縮技術會記錄為『100個1』而不是真的有100個1的位存在!這樣也能夠精簡文件記錄的容量!
簡單的說,你可以將文件壓縮原理想成,其實文件里面有相當多的空間存在,並不是完全填滿的, 而壓縮的技術就是將這些空間填滿,以讓整個文件占用的容量下降!不過,這些壓縮過的文件並無法直接被我們的操作系統所使用的,因此, 若要使用這些被壓縮過的文件數據,則必須將他還原回來未壓縮前的模樣, 那就是所謂的解壓縮!而至於壓縮前與壓縮后的文件所占用的磁碟空間大小, 就可以被稱為是壓縮比!
擴展:
WWW網站壓縮技術蠻有趣的!他讓你網站上面『看的到的數據』在經過網絡傳輸時,使用的是『壓縮過的數據』, 等到這些壓縮過的數據到達你的計算機主機時,再進行解壓縮,由於目前的計算機運算速度相當的快速, 因此其實在網頁瀏覽的時候,時間都是花在『數據的傳輸』上面,而不是 CPU 的運算啦!如此一來,由於壓縮過的數據量降低了,自然傳送的速度就會增快不少!
Linux常見的壓縮命令
命令 | 壓縮比 | 后綴名 | 查看壓縮后的文件內容命令 |
---|---|---|---|
compress | + | .Z | - |
gzip | ++ | .gz | zcat |
bzip2 | +++ | .bz2 | bzcat |
強調,compress 已經很少人在使用了,因為這支程序無法解開 *.gz 的文件,而 gzip 則可以解開 *.Z 的文件。 |
- *.Z compress 程序壓縮的文件;
- *.gz gzip 程序壓縮的文件;
- *.bz2 bzip2 程序壓縮的文件;
- *.tar tar 程序打包的數據,並沒有壓縮過;
- *.tar.gz tar 程序打包的文件,其中並且經過 gzip 的壓縮
- *.tar.bz2 tar 程序打包的文件,其中並且經過 bzip2 的壓縮
Linux上常見的壓縮命令就是 gzip 與 bzip2 ,至於 compress 已經退流行了。 gzip 是由 GNU計划 所開發出來的壓縮命令,該命令已經取代了 compress 。 后來 GNU計划 又開發出 bzip2 這個壓縮比更好的壓縮命令!不過,這些命令通常僅能針對一個文件來壓縮與解壓縮,如此一來, 每次壓縮與解壓縮都要一大堆文件,豈不煩人?此時,打包軟件tar就顯的很重要啦!
這個 tar 可以將很多文件打包成為一個文件!甚至是目錄也可以這么玩。不過,單純的 tar 功能僅是打包而已,即將很多文件整理成為一個文件, 事實上,他並沒有提供壓縮的功能,后來,GNU計划中,將整個 tar 與壓縮的功能結合在一起,如此一來提供使用者更方便並且更強大的壓縮與打包功能! 底下我們就來談一談這些在 Linux 底下基本的壓縮命令吧!
擴展:什么是GNU,FSF,GPL?
- GNU:Gnu's Not Unix 的縮寫, 官網1984年史托曼開始着手GNU計划,這個計划的目的建立一個自由的開放的UNIX.但是寫一個UNIX非常困難,所以史托曼打算先寫運行在UNIX的小程序.但所有的軟件都需要編譯器編譯源代碼,史托曼決定先一個C語言的編譯器(GUN C gcc)。但編譯器也寫得並不順利,於是,他寫了Emacs編輯器.因了Emacs很得非常好,史托曼賺了一點錢,從而開始全力編寫其他軟件.當史托曼在成立自由軟件基金會(Free Software Foundation,FSF)后,他請了請了更多的工程師和志願者在編寫軟件,終於完成GCC的編寫。
- FSF:Free Software Foundation的縮寫,官網, 創立於1985年,負責GNU Project的運營。
- GPL: General Public License的縮寫。1985年,為了避免GNU所開發的自由軟件被其他人修改而成為版權軟件,史托曼與律師草擬了有名的通用公共許可證(General Public License , GPL)。
gzip命令
選項與參數:
- -c :將壓縮的數據輸出到螢幕上,可透過數據流重導向來處理;將壓縮數據輸出到標准輸出中,並保留源文件。
- -d :解壓縮的參數;
- -t :可以用來檢驗一個壓縮檔的一致性~看看文件有無錯誤;
- -v :可以顯示出原文件/壓縮文件的壓縮比等資訊;
- -r : 遞歸壓縮指定目錄下以及子目錄下的所有文件。
- -# :壓縮等級,-1 最快,但是壓縮比最差、-9 最慢,但是壓縮比最好!默認是 -6
bzip2命令
若說 gzip 是為了取代 compress 並提供更好的壓縮比而成立的,那么 bzip2 則是為了取代 gzip 並提供更佳的壓縮比而來的。 bzip2 的用法幾乎與 gzip 相同!
選項與參數:
- -c :將壓縮的過程產生的數據輸出到螢幕上!將壓縮數據輸出到標准輸出中,並保留源文件。
- -d :解壓縮的參數
- -k :保留原始文件,而不會刪除原始的文件喔!
- -z :壓縮的參數
- -v :可以顯示出原文件/壓縮文件的壓縮比等資訊;
- -r : 遞歸壓縮指定目錄下以及子目錄下的所有文件。
- -# :與 gzip 同樣的,都是在計算壓縮比的參數, -9 最佳, -1 最快!
gzip壓縮目錄實例:
/home/test目錄建立a.txt,b.txt,c.txt文件,內容如下:
[root@localhost test]# ls
a.txt b.txt c.txt
[root@localhost test]# cat a.txt
11111111111111111111111111111
11111111111111111111111111111
1111111111111111111111111111
111111111111111111111111111
[root@localhost test]# cat b.txt
22222222222222222222222222222
222222222222222222222222222
22222222222222222222222222222222222
22222222222222222222222222222
[root@localhost test]# cat c.txt
3333333333333333333333333333
33333333333333333333333333333
333333333333333333333
[root@localhost test]#
使用gzip直接壓縮test目錄,可以看到是將目錄內的所有文件 "分別" 進行壓縮:
[root@localhost test]# gzip /home/test
gzip: /home/test is a directory -- ignored
[root@localhost test]# gzip -r /home/test
[root@localhost test]# ls
a.txt.gz b.txt.gz c.txt.gz
[root@localhost test]#
打包命令tar
前一小節談到的命令大多僅能針對單一文件來進行壓縮,雖然 gzip 與 bzip2 也能夠針對目錄來進行壓縮, 不過,這兩個命令對目錄的壓縮指的是將目錄內的所有文件 "分別" 進行壓縮的動作! 而不像在 Windows 的系統,可以使用類似 WinRAR 這一類的壓縮軟件來將好多數據打包成一個文件的樣式。
這種將多個文件或目錄包成一個大文件的命令功能,我們可以稱呼他是一種打包命令! 那 Linux 這種打包命令就是 tar命令。tar 可以將多個目錄或文件打包成一個大文件,同時還可以通過 gzip/bzip2 的支持將該文件進行壓縮!
選項與參數:
- -c :創建打包文件,可搭配 -v 來察看過程中被打包的文件名(filename)
- -t :查看打包文件的內容含有哪些文件名,重點在查看文件名;
- -x :解打包或解壓縮的功能,可以搭配 -C (大寫) 在特定目錄解開
特別留意的是, -c、-t、-x 不可同時出現在一串命令列中。 - -j :通過 bzip2 的支持進行壓縮/解壓縮:此時文件名最好為 *.tar.bz2
- -z :通過 gzip 的支持進行壓縮/解壓縮:此時文件名最好為 *.tar.gz
- -v :在壓縮/解壓縮的過程中,將正在處理的文件名顯示出來!
- -f filename:-f 后面要立刻接要被處理的文件名!建議 -f 單獨寫一個選項!
- -C 目錄 : 改變至目錄 DIR。這個選項用在解壓縮,若要在特定目錄解壓縮,可以使用這個選項。這個用在壓縮,可以指定絕對路徑。
- -p :保留備份數據的原本權限與屬性,常用於備份(-c)重要的配置文件
- -P :保留絕對路徑,亦即允許備份數據中含有根目錄存在之意;
- --exclude=FILE:在壓縮的過程中,不要將 FILE 打包!
tar打包不壓縮實例
[root@localhost test]# tar -cv -f test.tar /home/test
tar: Removing leading `/' from member names
/home/test/
/home/test/a.txt
/home/test/b.txt
/home/test/c.txt
tar: /home/test/test.tar: file is the archive; not dumped
[root@localhost test]# ls
a.txt b.txt c.txt test.tar
[root@localhost test]#
注意:輸出第一句tar: Removing leading `/' from member names是警告,稍后解釋。
可以看到已經將目錄所有文件打包成一個文件test.tar,查看test.tar包內容:
[root@localhost test]# ls
a.txt b.txt c.txt test.tar
[root@localhost test]#
[root@localhost test]# tar -tv -f test.tar
drwxrwxrwx root/root 0 2021-05-23 02:29 home/test/
-rwxrwxrwx root/root 117 2021-05-23 02:11 home/test/a.txt
-rwxrwxrwx root/root 124 2021-05-23 02:11 home/test/b.txt
-rwxrwxrwx root/root 81 2021-05-23 02:11 home/test/c.txt
[root@localhost test]#
從上面的數據可以發現一件很有趣的事情,那就是每個文件名都沒了根目錄 / 了!這也是上面出現的那個警告信息**tar: Removing leading /' from member names**(移除了文件名開頭的
/' )所告知的情況!
那為什么要拿掉根目錄呢?主要是為了安全!我們使用 tar 備份的數據可能會需要解壓縮回來使用, 在 tar 所記錄的文件名(就是剛剛使用 tar -tv -f 所查看到的文件名) 那就是解包后的實際文件名。 如果拿掉了根目錄,假設你將備份數據在 /tmp 解開,那么解壓縮的文件名就會變成/tmp/home/test/xxx。 但如果沒有拿掉根目錄,解壓縮后的文件名就會是絕對路徑, 即解壓縮后的數據一定會被放置到 /home/test/xxx 去,如此一來,你的原本的 /home/test/ 底下的數據, 就會被備份數據所覆蓋過去了!
擴展:打包時忽略文件的目錄結構
[root@localhost test]# ls
a.txt b.txt c.txt
[root@localhost test]# tar -cvf test.tar -C /home/test *
a.txt
b.txt
c.txt
[root@localhost test]# ls
a.txt b.txt c.txt test.tar
[root@localhost test]# tar -tvf test.tar
-rwxrwxrwx root/root 117 2021-05-23 02:11 a.txt
-rwxrwxrwx root/root 124 2021-05-23 02:11 b.txt
-rwxrwxrwx root/root 81 2021-05-23 02:11 c.txt
[root@localhost test]#
[root@localhost test]# ls
a.txt b.txt c.txt
[root@localhost test]# tar -cvf test.tar -C /home/ test/
test/
test/a.txt
test/b.txt
test/c.txt
[root@localhost test]# ls
a.txt b.txt c.txt test.tar
[root@localhost test]# tar -tvf test.tar
-rwxrwxrwx root/root 117 2021-05-23 02:11 test/a.txt
-rwxrwxrwx root/root 124 2021-05-23 02:11 test/b.txt
-rwxrwxrwx root/root 81 2021-05-23 02:11 test/c.txt
[root@localhost test]#
tar打包壓縮實例
[root@localhost test]# tar -czvf test.tar.gz *
a.txt
b.txt
c.txt
[root@localhost test]# ls
a.txt b.txt c.txt test.tar.gz
[root@localhost test]# tar -tvf test.tar.gz
-rwxrwxrwx root/root 117 2021-05-23 02:11 a.txt
-rwxrwxrwx root/root 124 2021-05-23 02:11 b.txt
-rwxrwxrwx root/root 81 2021-05-23 02:11 c.txt
[root@localhost test]#