bzip2, bunzip2 -
一種塊排序檔案壓縮軟體,v0.9.5
bzcat -
將檔案解壓縮至標準輸出
bzip2recover - 恢復損壞的 bzip2 檔案
bzip2 [
-cdfkqstvzVL123456789 ] [
filenames ... ]
bunzip2 [
-fkvsVL ] [
filenames ... ]
bzcat [
-s ] [
filenames ... ]
bzip2recover filename
bzip2 採用 Burrows-Wheeler
塊排序文字壓縮演算法和
Huffman
編碼方式壓縮檔案。
壓縮率一般比基於 LZ77/LZ78
的壓縮軟體好得多,其效能接近
PPM 族統計類 壓縮軟體。
命令列引數有意設計為非常接近
GNU gzip
的形式,但也不完全相同。
bzip2
從命令列讀入檔名和引數。
每個檔案被名為
"原始檔名.bz2"
的壓縮檔案替換。
每個壓縮檔案具有與原檔案相同的修改時間、
許可權,
如果可能的話,
還具有相同的屬主,
因此在解壓縮時這些特性將正確地恢復。
在某些檔案系統中,
沒有許可權、
屬主或時間的概念,
或者對檔名的長度有嚴格限制,
例如 MSDOS,
在這種情況下,bzip2
沒有保持原檔名、
屬主、
許可權以及時間的機制,
從這個意義上說,bzip2
對檔名的處理是幼稚的。
bzip2 和
bunzip2
在預設情況下不覆蓋已有的檔案。
如果想覆蓋已有的檔案,要指定
-f 選項。
如果未指定檔名,
bzip2
將壓縮來自標準輸入的資料並寫往標準輸出。在這種情況下,
bzip2
會拒絕將壓縮結果寫往終端,因為這完全無法理解並且是沒有意義的。
bunzip2 (以及
bzip2 -d)
對所有指定的檔案進行解壓縮處理。不是由
bzip2
產生的檔案將被忽略,同時發出一個警告資訊。
bzip2
按下列方式由壓縮檔名確定解壓後的檔名:
filename.bz2 解壓成 filename
filename.bz 解壓成 filename
filename.tbz2 解壓成 filename.tar
filename.tbz 解壓成 filename.tar
anyothername 解壓成 anyothername.out
如果檔名的字尾不是下列之一:
.bz2, .bz, .tbz2 或
.tbz, .bzip2
將抱怨無法確定原始檔名,並採用原檔名加
.out 作為解壓縮檔名。
在壓縮時,如果不提供檔名,bzip2
將從標準輸入讀取資料,壓縮結果寫往標準輸出。
bunzip2
能夠正確地解壓由兩個或更多個壓縮檔案連在一起的檔案。
解壓的結果為相應的連在一起的未壓縮檔案。
bzip2
也支援對連在一起的壓縮檔案的完整性檢查(-t選項)。
同樣可採用 -c
選項將檔案壓縮或解壓縮至標準輸出。
多個檔案可透過這種方式壓縮或解壓縮。
輸出結果被依次送往標準輸出。
採用這種方式對多個檔案的壓縮將生成包含
多個壓縮檔案的資料流。這樣的資料流只能被
0.9.0 版或其後續版本的
bzip2
正確解壓。較早版本的
bzip2
會在解壓完第一個檔案之後停止。
bzcat (或
bzip2 -dc)
將所有指定檔案解壓縮至標準輸出。
bzip2 可從環境變數
BZIP2
和
BZIP
中依次讀取引數,
並在命令列引數之前對其進行處理。
這是提供預設選項的方便途徑。
即使壓縮後的檔案略大於原檔案,
壓縮也總是照樣進行。
小於大約 100
位元組的檔案壓縮後傾向於變大,
因為會有一個 50
位元組的資料頭。
對於隨機資料
(包括大多數壓縮軟
件的輸出),
大約每位元組壓成 8.05
位, 放大率約為 0.5%。
bzip2 採用 32 位 CRC
校驗碼作自我檢查,以確認解壓後的檔案與原始檔案相同。
這可用於檢測壓縮檔案是否損壞,並防止
bzip2
中未知的缺陷(運氣好的話這種可能性非常小)。
資料損壞而未檢測到的機率非常之小,
對於每個被處理的檔案大約是四十億分之一。
檢查是在解壓縮時進行的,
因此它只能說明某個地方出問題了。
它能幫助恢復原始未壓縮的資料。可以用
bzip2recover
來嘗試從損壞的檔案中恢復資料。
返回值:正常退出返回
0, 出現環境問題返回 1
(檔案未找到,非法的選項,I/O錯誤等),
返回 2
表明壓縮檔案損壞,出現導致
bzip2
緊急退出的內部一致性錯誤(例如缺陷)時返回
3。
- -c --stdout
- 將資料壓縮或解壓縮至標準輸出。
- -d --decompress
- 強制解壓縮。
bzip2, bunzip2 以及 bzcat
實際上是同一個程式,進行何種操作將根據程式名確定。
指定該選項後將不考慮這一機制,強制
bzip2 進行解壓縮。
- -z --compress
- -d
選項的補充:強制進行壓縮操作,而不管執行的是哪個程式。
- -t --test
- 檢查指定檔案的完整性,但並不對其解壓縮。
實際上將對資料進行實驗性的解壓縮操作,而不輸出結果。
- -f --force
- 強制覆蓋輸出檔案。通常
bzip2
不會覆蓋已經存在的檔案。該選項還強制
bzip2
打破檔案的硬連線,預設情況下
bzip2 不會這麼做。
- -k --keep
- 在壓縮或解壓縮時保留輸入檔案(不刪除這些檔案)。
- -s --small
- 在壓縮、
解壓縮及檢查時減少記憶體用量。
採用一種修正的演算法進行壓縮和測試,
每個資料塊僅需要 2.5
個位元組。
這意味著任何檔案都可以在
2300k
的記憶體中進行解壓縮,
儘管速度只有通常情況下的一半。
在壓縮時,-s將選定 200k
的塊長度,記憶體用量也限制在
200k 左右,
代價是壓縮率會降低。
總之,如果機器的記憶體較少(8兆位元組或更少),
可對所有操作都採用-s選項。參見下面的記憶體管理。
- -q --quiet
- 壓制不重要的警告資訊。屬於
I/O
錯誤及其它嚴重事件的資訊將不會被壓制。
- -v --verbose
- 詳盡模式 --
顯示每個被處理檔案的壓縮率。
命令列中更多的 -v
選項將增加詳細的程度,
使 bzip2
顯示出許多主要用於診斷目的資訊。
- -L --license -V --version
- 顯示軟體版本,許可證條款及條件。
- -1 to -9
- 在壓縮時將塊長度設為
100 k、200 k .. 900 k。
對解壓縮沒有影響。參見下面的記憶體管理。
- --
- 將所有後面的命令列變數看作檔名,即使這些變數以減號"-"打頭。
可用這一選項處理以減號"-"打頭的檔名,
例如:bzip2 -- -myfilename.
- --repetitive-fast --repetitive-best
- 這些選項在 0.9.5
及其以上版本中是多餘的。
在較早的版本中,這兩個選項對排序演算法
的行為提供了一些粗糙的控制,有些情況下很有用。
0.9.5
及其以上版本採用了改進的演算法而與這些選項無關。
bzip2
按照資料塊壓縮大檔案。
資料塊長度同時影響資料的壓縮率和壓縮及解壓縮時需要
的記憶體用量。 選項 -1
至 -9
將資料塊長度分別指定為
100,000 位元組至
900,000(預設)位元組。
在解壓縮時,
壓縮時使用的塊長度從壓縮檔案的頭中讀取,
同時
bunzip2
分配出剛好夠用的記憶體對檔案進行解壓縮。
由於資料塊長度儲存在壓縮檔案中,
所以在解壓縮時不需要
-1 至 -9 這些選項,
因而將被忽略。
可以按下面的公式估計壓縮和解壓縮時的記憶體用量,單位為位元組:
壓縮: 400k + ( 8 x 資料塊長度 )
解壓縮: 100k + ( 4 x 資料塊長度
), 或
100k + ( 2.5 x 資料塊長度 )
大資料塊長度產生迅速縮小的臨界返回
(give rapidly diminishing marginal returns)。
在小機器上使用
bzip2
時,
一個值得記住的事實是,
大多數壓縮來自資料塊長度的前
200 或 300k。
另外重要的一點是,
解壓縮時記憶體的需要量是在壓縮時用塊長度選項設定的。
對於預設用 900k
的資料塊長度壓縮的檔案,
bunzip2 大約需要 3700k
位元組的記憶體進行解壓縮。為支援一臺
4MB
機器上任何檔案的解壓縮,
bunzip2
有一個選項大約只需一半容量的記憶體,約
2300k 位元組。
解壓縮速度同樣也降低一半。
因此應該只在需要時採用該選項。相應的選項標誌為
-s。
一般來說,應儘量採用記憶體允許的最大資料塊長度,
因為這能達到最好的壓縮率,
壓縮和解壓縮速度實質上不受塊長度的影響。
另一個值得注意的問題是關於小於一個數據塊長度的檔案的,
也就是說, 所遇到的
大多數檔案使用一個大資料塊。
由於檔案長度小於一個數據塊長度,
實際使用到的記憶體與檔案長度成正比。
例如,採用 -9
選項壓縮一個 20,000
位元組的檔案時,
將分配 7600k 的記憶體,
但其中只用到了 400k+20000*8=560k
位元組。同樣地,在解壓縮時將分配
3700k 記憶體,但只用到 100k +
20000 * 4 = 180 k 位元組。
下表總結了不同資料塊長度下的記憶體用量。同時列出的還有
Calgary 文字壓縮語料
庫中的 14
個檔案的壓縮長度,這
14
個檔案壓縮前總長度為
3,141,622 位元組。
這些資料顯示了壓縮率是如何隨資料塊長度變化的。
由於這一語料庫主要由小檔案組成,
所以這些數字並沒有充分體現出大檔案情況下,
採用大資料塊所能達到的較高壓縮率的優勢。
壓縮時 解壓縮 解壓縮 -s
語料庫檔案
Flag 記憶體用量
記憶體用量
選項記憶體用量
壓縮長度
-1 1200k 500k 350k 914704
-2 2000k 900k 600k 877703
-3 2800k 1300k 850k 860338
-4 3600k 1700k 1100k 846899
-5 4400k 2100k 1350k 845160
-6 5200k 2500k 1600k 838626
-7 6100k 2900k 1850k 834096
-8 6800k 3300k 2100k 828642
-9 7600k 3700k 2350k 828642
bzip2
按資料塊對資料進行壓縮,資料塊長度通常為
900k
位元組。每個資料塊被獨立地處理。
如果由於介質或傳輸錯誤導致多資料塊的
.bz2
檔案損壞,有可能將檔案中未損壞的
資料塊中的資料恢復。
壓縮後的資料塊以一個
48
位的結構分界,因而有可能在合理的範圍內找到塊邊界。
每個資料塊也帶著自己的
32 位 CRC
校驗碼,因此可以區分損壞與未損壞的資料塊。
bzip2recover
是一個簡單的程式,它的功能是在
.bz2
檔案中尋找資料塊,並將每個資料塊寫到
自己的 .bz2
檔案中。然後可以用
bzip2 -t
測試結果的完整性,將未損壞的部分解壓縮。
bzip2recover
只有一個命令列變數,即損壞檔案的名字。輸出結果是一系列象
"rec0001file.bz2"、 "rec0002file.bz2"
這樣的檔案,
每個檔案含有從損壞檔案中找出的資料塊。
輸出檔名設計為在接下來的處理中可方便地使用萬用字元,
例如,"bzip2 -dc
rec*file.bz2>recovered_data",可按正確的次序列出檔案。
bzip2recover
在處理大檔案時最有用,
因為大檔案含有很多資料塊。
顯然用它處理單個數據塊的損壞檔案不會有任何結果,
因為一個損壞的資料塊是無法恢復的。
如果想盡量減少潛在的由於介質及傳輸錯誤導致的資料損壞,
可以考慮採用較小的資料塊長度進行壓縮。
在壓縮的排序階段,
相似的字串將被聚集在一起。
因此,
對於包含很長重複符號
的檔案, 例如象
"aabaabaabaab......"
這樣的字串(重複幾百次),
壓縮速度會
比通常情況慢得多。 0.9.5
及其以上版本在處理這樣的重複時,
速度比以前版本提高
了很多。
最壞情況與平均情況下的壓縮時間之比約為
10:1。 對於以前的版本,
這一數字大約是 100:1
以上。你如果願意,
可採用 -vvvv
選項來非常詳細地監視這一過程。
解壓縮速度並不受這些現象的影響。
bzip2
通常分配出幾兆位元組的記憶體用於處理資料,
對這些記憶體的訪問是以相當隨機的方式
進行的。 這意味著,
壓縮及解壓縮的效能在很大程度上取決於機器上處理快取記憶體
未命中的速度。
因此,
已經觀察到對程式作很小的減少失敗率的改動會導致不成比例的很大的效能
上的提升。 我設想
bzip2
在有大量快取記憶體機器上的效能最佳。
I/O
錯誤資訊並不是很有用。
bzip2 會盡量探測 I/O
錯誤資訊並乾淨地退出,
但問題的細節有時看上去很容易引起誤解。
本手冊頁適用於 0.9.5 版的
bzip2。 由這一版本的 bzip2
產生的壓縮資料與以前的公開版本
0.1pl2、0.9.0 完全相容,
但有一個例外:0.9.0
及其以上版本能正確解壓縮多個連在一起的壓縮檔案,0.1pl2
則不能,
它將在解壓縮完資料流中的第一個檔案之後停止。
bzip2recover 採用 32
位的整型數表示壓縮檔案中位的位置,
因此它無法處理大於 512
兆位元組的檔案。
但這一問題很容易解決。
Julian Seward,
[email protected].
http://www.muraroa.demon.co.uk
bzip2
包含的想法及概念至少歸功於下列人員:
Michael Burrows 和 David
Wheeler(塊排序變換), David
Wheeler(Huffman 編碼器), Peter
Fenwick(原始 bzip
的結構程式設計模型及許多改進),Alistair
Moffat、 Ian Witten(原始 bzip
中的演算法編碼)。
我非常感激他們的幫助、
支援以及建議。
參見源釋出的手冊中有關文件來源中的線索。
Christian von Roques
曾鼓勵我尋找更快的排序演算法,
以提高壓縮速度。 bela Lubkin
曾鼓勵我改進最壞情況下的壓縮效能。
很多人給我發來修補程式,
幫助解決移植問題,
租借機器,提出建議等。
Liu JingSong <[email protected]>
2001/01/31
http://cmpp.linuxforum.net
本頁面中文版由中文 man
手冊頁計劃提供。
中文 man 手冊頁計劃:
https://github.com/man-pages-zh/manpages-zh