檔案與文件系統壓縮與打包

壓縮的用途與技術: 

您是否有過文件檔案太大,導致無法以一片軟盤將他複製完成的困擾?又,您是否有過,發現一個軟件裏面有好多檔案,這些檔案要將他複製與攜帶都很不方便的問題?還有,您是否有過要備份某些重要數據,偏偏這些數據量太大了,耗掉了你很多的硬盤與磁盤空間呢?這個時候,那個好用的『檔案壓縮』技術可就派的上用場了!因爲這些比較大型的檔案透過所謂的檔案壓縮技術之後,可以將他的磁盤使用量降低,可以達到減低檔案容量的效果,此外,有的壓縮程序還可以進行容量限制,使一個大型檔案可以分割成爲數個小型檔案,以方便軟盤片攜帶呢! 

  

那麼什麼是『檔案壓縮』呢?我們來稍微談一談他的原理好了。目前我們使用的計算機系統中都是使用所謂的 bytes 單位來計量的!不過,事實上,計算機最小的計量單位應該是 bits 纔對啊,此外,我們也知道 1 byte = 8 bits 。但是如果今天我們只是記憶一個數字,亦即是 1 這個數字呢?他會如何記錄?假設一個 byte 可以看成底下的模樣:(注:由於 1 byte = 8 bits ,所以每個 byte 當中會有 8 個空格,而每個空格可以是 0, 1 ,這裏僅是做爲一個約略的介紹,讀者不必刻意記憶 ) 

□□□□□□□□

而由於我們記錄數字是 1 ,考慮計算機所謂的二進制喔,如此一來, 1 會在最右邊佔據 1 個 bit ,而其它的 7 個 bits 將會自動的被填上 0 囉!你看看,其實在這樣的例子中,那 7 個 bits 應該是『空的』纔對!不過,爲了要滿足目前我們的操作系統數據的存取,所以就會將該數據轉爲 byte 的型態來記錄了!而一些聰明的計算機工程師就利用一些複雜的計算方式,將這些沒有使用到的空間『丟』出來,以讓檔案佔用的空間變小!這就是壓縮的技術啦!簡單的說,你可以將他想成,其實檔案裏面有相當多的『空間』存在,並不是完全填滿的,而『壓縮』的技術就是將這些『空間』填滿,以讓整個檔案佔用的容量下降!不過,這些『壓縮過的檔案』並無法直接被我們的操作系統所使用的,因此,若要使用這些被壓縮過的檔案數據,則必須將他『還原』回來未壓縮前的模樣,那就是所謂的『解壓縮』囉!而至於壓縮前與壓縮後的檔案所佔用的磁盤空間大小,就可以被稱爲是『壓縮比』囉!更多的技術文件或許你可以參考一下 GNU 計劃當中關於壓縮指令 gzip 的說明文件。當然,我 這裏 也保留一份數據,做爲未來參考之用呢! 

  

這個『壓縮』與『解壓縮』的動作有什麼好處呢?最大的好處就是壓縮過的檔案容量變小了,所以你的硬盤容量無形之中就可以容納更多的數據,此外,在一些網絡數據的傳輸中,也會由於數據量的降低,好讓網絡頻寬可以用來作更多的工作!而不是老是卡在一些大型的檔案上面呢!目前很多的 WWW 網站也是利用檔案壓縮的技術來進行數據的傳送,好讓網站的可利用率上升喔!( 注:這種技術蠻有趣的!他讓您網站上面『看的到的數據』在經過網絡傳輸時,使用的是『壓縮過的數據』,等到這些壓縮過的數據到達你的計算機主機時,再進行解壓縮,由於目前的計算機運算速度相當的快速,因此其實在網頁瀏覽的時候,時間都是花在『數據的傳輸』上面,而不是 CPU 的運算啦!,如此一來,由於壓縮過的數據量降低了,自然傳送的速度就會增快不少! )若您是一位軟件工程師,那麼相信您也會喜歡將你自己的軟件壓縮之後提供大家下載來使用,畢竟沒有人喜歡自己的網站天天都是頻寬滿載的吧?!舉個例子來說, Linux 2.4.19 完整的核心大小約有 200 MB 左右,而由於核心主要多是 ASCII code 的存文字型態檔案,這種檔案的『多餘空間』最多了。而一個提供下載的壓縮過的 2.4.19 核心大約僅有 30MB 左右,差了幾倍呢?您可以自己算一算喔!


--------------------------------------------------------------------------------

Linux 壓縮檔案的附檔名 

如果您常常在網絡上面捉 Linux 的數據下來玩的話,大概會曉得的是,這些供人下載的檔案通常都是『壓縮』過的!爲了什麼?上面已經稍微提過啦!呵呵!壓縮過的檔案具有節省頻寬、節省磁盤空間等等的優點,並且還方便攜帶呢! ^_^ !而,您應該也會知道,這些被壓縮過的檔案,通常其附檔名都是『 *.tar, *.tar.gz, *.tgz, *.gz, *.Z, *.bz2 』等等的,爲什麼要訂定這些壓縮檔案附檔名爲這樣的模樣呢?這是因爲在 Linux 上面壓縮的指令相當的多,並且,這些壓縮指令可能無法針對每種壓縮檔案都可以解的開,畢竟目前的壓縮技術五花八門,每種壓縮計算的方法都不是完全相同的,所以囉,當你捉到某個壓縮檔時,自然就需要知道壓縮他的是那個指令啦,好用來對照着解壓縮啊! ^_^!也就是說,雖然 Linux 檔案的屬性基本上是與文件名沒有絕對關係的,能不能執行與他的檔案屬性有關而已,與文件名的關係很小!但是,爲了幫助我們小小的人類腦袋瓜子,所以適當的文件名稱附檔名還是必要的!因此,目前就有一些常常見到的壓縮檔案的附檔名啦!我們僅列出常見的幾樣在底下,給大家權做參考之用: 

 *.Z       compress 程序壓縮的檔案; 

 *.bz2     bzip2 程序壓縮的檔案; 

 *.gz      gzip 程序壓縮的檔案; 

 *.tar     tar 程序打包的數據,並沒有壓縮過; 

 *.tar.gz  tar 程序打包的檔案,其中並且經過 gzip 的壓縮! 

目前常見的壓縮程序主要就是如同上面提到的附檔名對應的那些指令啦!最早期的要算是 compress 這個傢伙了,而後,後來的 GNU 計劃開發出新一代的壓縮指令 gzip ( GNU zip ) 用來取代 compress 這個老牌的壓縮指令,再來還有 bzip2 這個壓縮比更好的壓縮指令呢!不過,這些指令通常僅能針對一個檔案來壓縮與解壓縮,如此一來,每次壓縮與解壓縮都要一大堆檔案,豈不煩人?,此時,那個所謂的『打包軟件』就顯的很重要啦!在 Unix-Like 當中,有個軟件很好玩,他就是 tar 這支程序!這個 tar 可以將很多檔案『打包』成爲一個檔案!甚至是目錄也可以這麼玩。不過,單純的 tar 功能僅是『打包』而已,亦即是將很多檔案集結成爲一個檔案,事實上,他並沒有提供壓縮的功能,後來, GNU 計劃中,將整個 tar 與壓縮的功能結合在一起,如此一來提供使用者更方便並且更強大的壓縮與打包功能! 

  

底下我們就來談一談這些在 Linux 底下基本的壓縮指令吧! 


--------------------------------------------------------------------------------


compress: 

語法: [root @test /root ]# compress [-d] filename  

參數說明:  

-d  :解壓縮的參數!  

範例:  

先 copy /etc/man.config 到 root 底下,再將他壓縮看看 

[root @test /root]# cp /etc/man.config /root 

[root @test /root]# compress man.config 

[root @test /root]# compress -d man.config.Z  

[root @test /root]# uncompress man.config.Z 

這是用來壓縮與解壓縮附檔名爲 *.Z 的指令!所以看到 *.Z 的檔案時,就應該要知道他是經由 compress 這個程序壓縮的呦!這是最簡單的壓縮指令囉!不過,使用的時候需要特別留意的是,當你以 compress 壓縮之後,如果沒有下達其它的參數,那麼原本的檔案就會被後來的 *.Z 所取代!以上面的案例來說明:原本壓縮的檔案爲 man.config ,那麼當壓縮完成之後,將只會剩下 man.config.Z 這個經過壓縮的檔案囉!那麼解壓縮呢?呵呵,則是將 man.config.Z 解壓縮成 man.config !使用上很簡單啦!解壓縮除了可以使用 compress –d 這個參數之外,也可以直接使用 uncompress !意思相同啦! 

  


--------------------------------------------------------------------------------


gzip, zcat: 

語法: [root @test /root ]# gzip [-d#] filename <==壓縮與解壓縮 

[root @test /root ]# zcat filename.gz     <==讀取壓縮檔內容 

參數說明:  

-d  :解壓縮的參數!  

-#  :壓縮等級, 1 最不好, 9 最好, 6 是默認值!  

範例:  

[root @test /root]# gzip man.config       

會產生 man.config.gz 這個檔案  

[root @test /root]# zcat man.config.gz 

會讀取出 man.config 的內容 


[root @test /root]# gzip -d man.config.gz  

[root @test /root]# gunzip man.config.gz 

解壓縮,產生 man.config 這個檔案 


[root @test /root]# gzip -9 man.config      

以最大壓縮比壓縮 testing 這個檔案!

 

gzip 是用來壓縮與解壓縮附檔名爲 *.gz 的指令!所以看到 *.gz 的檔案時,就應該要知道他是經由 gzip 這個程序壓縮的呦!另外, gzip 也提供 壓縮比的服務! -1 是最差的壓縮比,但是壓縮速度最快,而 -9 雖然可以達到較佳的壓縮比(經過壓縮之後,檔案比較小一些!),但是卻會損失一些速度!預設是 -6 這個數值! gzip 也是相當常使用的一個壓縮指令呢!至於 zcat 則是用來讀取壓縮文件數據內容的指令!假如我們剛剛壓縮的檔案是一個文字文件,那麼你還記得如何讀取文字文件嗎?!沒錯!就是使用 cat ,那麼讀取壓縮檔呢?呵呵!就是使用 zcat 囉!由於 gzip 這個壓縮指令主要想要用來取代 compress 的,所以 compress 的壓縮檔案也可以使用 gzip 來解開喔!同時, zcat 這個指令可以同時讀取 compress 與 gzip 的壓縮檔呦! 

  


--------------------------------------------------------------------------------


bzip2, bzcat: 

語法: [root @test root]# bzip2 [-dz] filename <==壓縮解壓縮指令 

[root @test root]# bzcat filename.bz2   <==讀取壓縮文件內容指令 

參數說明: 

-d  :解壓縮的意思! 

-z  :壓縮的意思! 

範例: 

同樣的,我們以剛剛拷貝過來的 /root/man.config 這個檔案爲例 

[root @test root]# bzip2 –z man.config 

[root @test root]# bzcat man.config.bz2 

[root @test root]# bzip2 –d man.config.bz2 

[root @test root]# bunzip2 man.config.bz2 

剛剛的 compress 附檔名自動建立爲 .Z ,這裏的 bzip2 則是自動的將附檔名建置爲 .bz2 囉!所以當我們使用具有壓縮功能的 bzip2 –z 時,那麼剛剛的 man.config 就會自動的變成了 man.config.bz2 這個檔名囉!好了,那麼如果我想要讀取這個檔案的內容呢?是否一定要解開?當然不需要囉!可以使用簡便的 bzcat 這個指令來讀取內容即可!例如上面的例子中,我們可以使用 bzcat man.config.bz2 來讀取數據而不需要解開!此外,當您要解開一個壓縮檔時,這個檔案的名稱爲 .bz, .bz2, .tbz, .tbz2 等等,那麼就可以嘗試使用 bzip2 來解看看啦!當然囉,也可以使用 bunzip2 這個指令來取代 bzip2 –d 囉 

  


--------------------------------------------------------------------------------


tar: 

語法: [root @test /root ]# tar [-zxcvfpP] filename  

[root @test /root ]# tar -N 'yyyy/mm/dd' /path -zcvf target.tar.gz source  

參數說明:  

-z  :是否同時具有 gzip 的屬性?  

-x  :解開一個壓縮檔案的參數指令!  

-t  :查看 tarfile 裏面的檔案! 

-c  :建立一個壓縮檔案的參數指令  

-v  :壓縮的過程中顯示檔案!  

-f  :使用檔名,請留意,在 f 之後要立即接檔名喔!不要再加參數! 

   例如使用『 tar -zcvfP tfile sfile』就是錯誤的寫法,要寫成 

   『 tar -zcvPf tfile sfile』纔對喔! 

-p  :使用原檔案的原來屬性(屬性不會依據使用者而變)  

-P  :可以使用絕對路徑  

-N  :比後面接的日期(yyyy/mm/dd)還要新的纔會被打包進新建的檔案中!  

--exclude FILE:在壓縮的過程中,不要將 FILE 打包!  

範例:  

[root @test /root]# tar -cvf  directory.tar    directory  

只將目錄整合打包成一個檔案  

[root @test /root]# tar -zcvf directory.tar.gz directory  

除了將目錄打包外,同時以 gzip 壓縮  


[root @test /root]# tar -zcvf filename.tar.gz  /home/test/*  

將 /home/test/ 這個目錄下的檔案全部打包並壓縮成爲一個 filename.tar.gz 的檔案 


[root @test /root]# tar -xvf  directory.tar  

解 tar 的封包,請注意,由於沒有 gzip (.tar 而非 .tar.gz) 的作用,所以只要使用 –xvf 即可!不需要加上 z ,否則會顯示有問題! 


[root @test /root]# tar -zxvf directory.tar.gz  

這個就是有加上 gzip 的壓縮的結果!所以需要加上 –z 呦! 


[root @test /root]# tar –ztvf directory.tar.gz 

這個 t 可以用來查看 tar 裏面的檔案信息呢!而不需要將他解開! 


[root @test /root]# tar -zcvPf home.tar.gz /home  

則建立起來的壓縮檔內檔案爲絕對路徑  

請注意,使用這個 P 的參數時,不要將 P 加在 f 後面,因爲 

f 之後要立即接檔名才行喔! 


[root @test /root]# tar -N '2002/06/25' -zcvf home.tar.gz /home  

上面是說 在 /home 這個目錄中,比 2002/06/25 日還要新的檔案纔會被打包進入 home.tar.gz 這個檔案中!  


[root @test /root]# tar -zcvf host.tar.gz / --exclude /mnt --exclude /proc  

上面是說,將根目錄的所有數據都打包進 host.tar.gz 這個檔案中,但是 /mnt 及 /proc 則不打包!  


[root @test /root]# tar -cvf - /home | tar -xvf - 

上面的意思是『將 /home 打包之後,直接解壓縮在 /root 底下!』嘿嘿!不需要再建立一次中間檔案!不過,使用上面的語法最好使用『絕對路徑』,比較不會有問題!這個方式適合不想要建立中間檔案時!

 


這是一個多用途的壓縮指令!剛剛我們提到的 compress 與 gzip 是可以適用在一個檔案的壓縮上面,但是如果是要壓縮一個目錄呢?!這時該如何是好?!呵呵! tar 就派上用場了! tar 可以將整個目錄或者是規定的檔案都整合成一個檔案!例如上面的第三個範例,他可以將 /home/test 底下的檔案全部整合成一個檔案!而第一個範例中,則是將目錄整合成一個檔案!同時, tar 可以配合 gzip (這個 gzip 的功能已經已經附加上 tar 裏面去了),同時整合並壓縮!呵呵!很方便吧!『 tar 用來作備份是很重要的指令! 』而由於 tar 整合過後的檔案我們通常會取名爲 *.tar ,而如果還含有 gzip 的壓縮屬性,那麼就取名爲 *.tar.gz 囉!取這個文件名只是爲了方便我們記憶這個檔案是什麼屬性罷了!並沒有實際的意義在! 

  

另外,需要注意的是,在使用的參數方面,有還有幾個有用的參數需要來了解一番,亦即是 -p 與 -P 這兩個!如果你曾經在 crontab 裏面下達過一些備份的指令時,那麼常常會收到 root 的信件,就是說,系統會告訴你『我將 / 的 tar 裏頭的內容拿掉了!』也就是說,原本你備份的檔案是 /home/test ,但是由於擔心未來你在解開壓縮的時候,會產生一些困擾,因爲在 tar 裏面的檔案如果是具有『絕對路徑』的話,那麼你解開的檔案將會『一定』在該路徑下也就是 /home/test,而不是絕對路徑(這裏請用心的想一想!),這樣子的最大困擾是,萬一有人拿走了你的這個檔案,並且將該檔案在他的系統上面解開!萬一他的系統上面正巧也有 /home/test 這個目錄,哈哈!他的檔案就會『正巧』被覆蓋了!所以囉,在預設的情況中,如果是以『絕對路徑』來建立打包檔案,那麼將會自動的將 / 拿掉!這是爲了剛剛說明的『安全』爲前提所做的默認值。好了!但是你就是要以絕對路徑來建立打包的檔案!那麼就加入 -P 這個參數吧(請注意!是大寫字符)!這樣就可以啦!那麼 -p 是什麼(小寫字符)?呵呵!那個 -p 是 permission 的意思,也就是『權限』啦!使用 -p 之後,被打包的檔案將不會依據使用者的身份來改變權限喔! 

  

這裏還有一個值得注意的參數呦!那就是在備份的情況中很常使用的 -N 的這個參數!你可以參考一下上面的例子就可以知道啦!在這個例子當中,相當重要的就是那個日期啦!在備份的情況當中,我們都希望只要備份較新的檔案就好了,爲什麼呢?因爲舊的檔案我們已經有備份囉!幹嘛還要再備份一次,浪費時間也浪費系統資源!這個時候此一參數就顯的相當的重要了啊! 

  

在上面的例子中,最後一個例子很有趣『tar cvf - /home | tar -xvf - 』!他是直接以管線命令『 pipe 』來進行壓縮、解壓縮的過程!在上面的例子中,我們想要『將 /home 底下的數據直接 copy 到目前所在的路徑,也就是 /root 底下來』,但是又覺得使用 cp -r 有點麻煩,那麼就直接以這個打包的方式來打包,其中,指令裏面的 - 就是表示那個被打包的檔案啦!由於我們不想要讓中間檔案存在,所以就以這一個方式來進行復制的行爲啦! 

  

tar 的功能相當的多,而由於他是經由『打包』之後再處理的一個過程,所以常常我們會聽到 tarball 的檔案,那就是經由 tar 打包再壓縮的檔案啦!此外, tar 也可以用在備份的儲存媒體上面,最常見的就是磁帶機了!假設我的磁帶機代號爲 /dev/st0 ,那麼我要將我的 /home 底下的數據都給他備份上去時,就是使用 tar /dev/st0 /home 就可以啦!很不錯吧! 

  

在 Linux 當中, gzip 已經被整合在 tar 裏面了!但是 Sun 或者其它較舊的 Unix 版本中, 當中的 tar 並沒有整合 gzip ,所以如果你需要解壓縮的話,就需要這麼做: 

  

gzip -d testing.tar.gz 

tar -xvf testing.tar 

 

第一個步驟會將檔案解壓縮,第二個步驟纔是將數據解出來!與其它壓縮程序不太一樣的是, bzip2, gzip 與 compress 在沒有加入特殊參數的時候,原先的檔案會被取代掉,但是使用 tar 則原來的與後來的檔案都會存在呦!

  


--------------------------------------------------------------------------------


cpio: 

語法: [root @test /root ]# cpio -covB  > [file|device]<==備份 

[root @test /root ]# cpio -icduv < [file|device]<==還原 

參數說明:  

-o :將資料 copy 輸出到檔案或裝置上  

-i :將數據自檔案或裝置 copy 出來系統當中  

-t :查看 cpio 建立的檔案或裝置的內容  

-c :一種較新的 portable format 方式儲存  

-v :讓儲存的過程中文件名稱可以在屏幕上顯示  

-B :讓預設的 Blocks 可以增加至 5120 bytes ,預設是 512 bytes !  

   這樣的好處是可以讓大檔案的儲存速度加快(請參考 i-nodes 的觀念)  

-d :自動建立目錄!由於 cpio 的內容可能不是在同一個目錄內, 

     如此的話在反備份的過程會有問題! 這個時候加上 -d 的話, 

     就可以自動的將需要的目錄建立起來了!  

-u :自動的將較新的檔案覆蓋較舊的檔案!  

範例:  

[root @test /root]# find / -print | cpio -covB > /dev/st0  

將搜尋到的檔案存到磁帶機  

[root @test /root]# cpio -icduv < /dev/st0  

將磁帶機的數據還原回來!  


[root @test /root]# cpio -icdvt < /dev/st0 > /tmp/content  

將磁帶機的內容(文件名而已)轉存到 /tmp/content  


[root @test /root]# find / -type -f | cpio -o > /tmp/root.cpio  

[root @test /root]# cpio -i < /tmp/root.cpio  

上面這個例子可以馬上實作看看!先輸出到 /tmp/root.cpio 這個檔案,然後再給他還原回來!

 

這個 cpio 還蠻神奇的呢!他最適用於備份的時候使用的一個指令了!爲什麼呢?因爲他並不像 cp 一樣,可以直接的將檔案給他 copy 過去,例如 cp * /tmp 就可以將所在目錄的所有檔案 copy 到 /tmp 底下,在 cpio 這個指令的用法中,由於 cpio 無法直接讀取檔案,而是需要『每一個檔案或目錄的路徑連同文件名一起』纔可以被記錄下來!因此, cpio 最常跟 find 這個指令一起使用了!這個 cpio 好像不怎麼好用呦!但是,嘿嘿!他可是備份的時候的一項利器呢!因爲他可以備份任何的檔案,包括 /dev 底下的任何裝置檔案!呵呵!所以他可是相當重要的呢!!您說是吧! 而由於 cpio 必需要配合其它的程序,例如 find 來建立檔名,所以, cpio 與管線命令及命令重導向的相關性就相當的重要了!上面的例子剛好可以用來複習一下上一章節裏面提到的內容!加油啦! 

  

備份:在備份的用法當中,他可以直接跟輸出到檔案或者是裝置當中,但是如前面說過的,你必須要配合 find 這個指令較好呦!那個 -o 表示將檔案或目錄輸出到右邊去的意思!還記得命令重導向嗎?對啦!就是那個東西囉!在上面的例子中,我們將備份的數據給他 copy 到磁帶機裏頭去!那個磁帶機的裝置代號就是 /dev/st0 囉! 

  

還原:那麼如何給他反過來解開呢?呵呵!可以直接給他下達 cpio -i 就是 input 就對啦!例如上頭的例子囉!這個指令可以多看看呢 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章