IO::Uncompress::Unzip - 讀取 zip 檔案/緩衝區
use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
my $status = unzip $input => $output [,OPTS]
or die "unzip failed: $UnzipError\n";
my $z = IO::Uncompress::Unzip->new( $input [OPTS] )
or die "unzip failed: $UnzipError\n";
$status = $z->read($buffer)
$status = $z->read($buffer, $length)
$status = $z->read($buffer, $length, $offset)
$line = $z->getline()
$char = $z->getc()
$char = $z->ungetc()
$char = $z->opened()
$status = $z->inflateSync()
$data = $z->trailingData()
$status = $z->nextStream()
$data = $z->getHeaderInfo()
$z->tell()
$z->seek($position, $whence)
$z->binmode()
$z->fileno()
$z->eof()
$z->close()
$UnzipError ;
# IO::File mode
<$z>
read($z, $buffer);
read($z, $buffer, $length);
read($z, $buffer, $length, $offset);
tell($z)
seek($z, $position, $whence)
binmode($z)
fileno($z)
eof($z)
close($z)
此模組提供一個 Perl 介面,可讓使用者讀取 zlib 檔案/緩衝區。
有關寫入 zip 檔案/緩衝區,請參閱附屬模組 IO::Compress::Zip。
此模組的主要目的是提供對 zip 檔案和緩衝區的串流讀取存取。
目前 IO::Uncompress::Unzip 支援下列壓縮方法
若要讀取 Bzip2 內容,必須安裝模組 IO::Uncompress::Bunzip2
。
若要讀取 LZMA 內容,必須安裝模組 IO::Uncompress::UnLzma
。
若要讀取 Xz 內容,必須安裝模組 IO::Uncompress::UnXz
。
若要讀取 Zstandard 內容,必須安裝模組 IO::Uncompress::UnZstd
。
提供頂層函數 unzip
,用於執行緩衝區和/或檔案之間的「一次性」解壓縮。若要更精細地控制解壓縮程序,請參閱 「OO 介面」 區段。
use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
unzip $input_filename_or_reference => $output_filename_or_reference [,OPTS]
or die "unzip failed: $UnzipError\n";
函數式介面需要 Perl5.005 或更新版本。
unzip
至少需要兩個參數,$input_filename_or_reference
和 $output_filename_or_reference
,以及零個或多個選用參數(請參閱 「選用參數」)
$input_filename_or_reference
參數參數 $input_filename_or_reference
用於定義壓縮資料的來源。
它可以採用下列形式之一
如果 $input_filename_or_reference
參數是簡單的純量,則假設它是一個檔案名稱。此檔案將開啟以供讀取,且輸入資料將從中讀取。
如果 $input_filename_or_reference
參數是檔案控制代碼,則輸入資料將從中讀取。字串「-」可用作標準輸入的別名。
如果 $input_filename_or_reference
是純量參考,則輸入資料將從 $$input_filename_or_reference
讀取。
如果 $input_filename_or_reference
是陣列參考,陣列中的每個元素都必須是檔案名稱。
輸入資料將依序從每個檔案中讀取。
將遍歷整個陣列,以確保在解壓縮任何資料之前,它只包含有效的檔案名稱。
如果 $input_filename_or_reference
是由字元「<」和「>」分隔的字串,unzip
會假設它是一個輸入 fileglob 字串。輸入是與 fileglob 匹配的檔案清單。
請參閱 File::GlobMapper 以取得更多詳細資訊。
如果 $input_filename_or_reference
參數是任何其他類型,將會傳回 undef
。
$output_filename_or_reference
參數參數 $output_filename_or_reference
用於控制未壓縮資料的目的地。此參數可以採用下列其中一種形式。
如果 $output_filename_or_reference
參數是單純的純量,則假設它是一個檔案名稱。此檔案將開啟以供寫入,且未壓縮的資料將寫入其中。
如果 $output_filename_or_reference
參數是檔案處理常式,未壓縮的資料將寫入其中。字串「-」可用作標準輸出的別名。
如果 $output_filename_or_reference
是純量參考,未壓縮的資料將儲存在 $$output_filename_or_reference
中。
如果 $output_filename_or_reference
是陣列參考,未壓縮的資料將推送到陣列中。
如果 $output_filename_or_reference
是由字元「<」和「>」分隔的字串,unzip
會假設它是一個輸出 fileglob 字串。輸出是與 fileglob 匹配的檔案清單。
當 $output_filename_or_reference
是檔案 glob 字串時,$input_filename_or_reference
也必須是檔案 glob 字串。其他任何情況都是錯誤。
請參閱 File::GlobMapper 以取得更多詳細資訊。
如果 $output_filename_or_reference
參數是任何其他類型,將會傳回 undef
。
當 $input_filename_or_reference
對應到多個壓縮檔案/緩衝區,而 $output_filename_or_reference
是單一檔案/緩衝區時,解壓縮後 $output_filename_or_reference
將包含來自每個輸入檔案/緩衝區所有未壓縮資料的串接。
一次性函數 unzip
的選用參數(大多數情況下)與在 "建構函數選項" 區段中定義的 OO 介面中使用的參數相同。例外情況如下列出
AutoClose => 0|1
此選項適用於任何輸入或輸出資料串流,而 unzip
是檔案處理常式。
如果指定 AutoClose
,且值為 true,則會在 unzip
完成後關閉所有輸入和/或輸出檔案處理常式。
此參數預設為 0。
BinModeOut => 0|1
此選項現在是 no-op。所有檔案都將以 binmode 寫入。
Append => 0|1
此選項的行為取決於輸出資料串流的類型。
緩衝區
如果啟用 Append
,所有未壓縮資料都將附加到輸出緩衝區的結尾。否則,在將任何未壓縮資料寫入輸出緩衝區之前,將會清除輸出緩衝區。
檔名
如果啟用 Append
,檔案將以附加模式開啟。否則,在將任何未壓縮資料寫入檔案之前,將會先截斷檔案的內容(如果有)。
檔案處理常式
如果啟用 Append
,在將任何未壓縮資料寫入檔案處理常式之前,將會透過呼叫 seek
將檔案處理常式定位到檔案結尾。否則,檔案指標不會移動。
當指定 Append
並將其設定為 true 時,它會將所有未壓縮資料附加到輸出資料串流。
因此,當輸出是檔案處理常式時,它會在寫入任何未壓縮資料之前執行 seek 到 eof。如果輸出是檔名,它將開啟以進行附加。如果輸出是緩衝區,所有未壓縮資料都將附加到現有緩衝區。
相反地,當未指定 Append
,或它存在且設定為 false 時,它將執行下列操作。
當輸出為檔案名稱時,它會在寫入任何未壓縮資料之前,截斷檔案的內容。如果輸出為檔案句柄,則其位置將不會改變。如果輸出為緩衝區,則在輸出任何未壓縮資料之前,它將會被清除。
預設為 0。
MultiStream => 0|1
如果輸入檔案/緩衝區包含多個壓縮資料串流,此選項將把整個批次解壓縮為單一資料串流。
預設為 0。
TrailingData => $scalar
在解壓縮完成後,傳回壓縮資料串流後立即存在的資料(如果有)。
當壓縮資料串流後緊接著有有用的資訊,而且您不知道壓縮資料串流的長度時,可以使用此選項。
如果輸入為緩衝區,trailingData
將傳回從壓縮資料串流的結尾到緩衝區結尾的所有內容。
如果輸入為檔案句柄,trailingData
將傳回壓縮資料串流的結尾到達後,檔案句柄輸入緩衝區中剩下的資料。然後,您可以使用檔案句柄讀取輸入檔案的其餘部分。
如果輸入為檔案名稱,請不要費心使用 trailingData
。
如果您在開始解壓縮之前知道壓縮資料串流的長度,您可以透過設定 InputLength
選項來避免使用 trailingData
。
假設您有一個只包含一個成員的 zip 檔案 file1.zip
,您可以像這樣讀取它,並將解壓縮的資料寫入檔案 file1.txt
。
use strict ;
use warnings ;
use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
my $input = "file1.zip";
my $output = "file1.txt";
unzip $input => $output
or die "unzip failed: $UnzipError\n";
如果您有一個包含多個成員的 zip 檔案,並且想要從檔案中讀取特定成員,例如 "data1"
,請使用 Name
選項
use strict ;
use warnings ;
use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
my $input = "file1.zip";
my $output = "file1.txt";
unzip $input => $output, Name => "data1"
or die "unzip failed: $UnzipError\n";
或者,如果您想要將 "data1"
成員讀取到記憶體中,請為 output
參數使用純量參照。
use strict ;
use warnings ;
use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
my $input = "file1.zip";
my $output ;
unzip $input => \$output, Name => "data1"
or die "unzip failed: $UnzipError\n";
# $output now contains the uncompressed data
從現有的 Perl 檔案句柄 $input
讀取,並將解壓縮的資料寫入緩衝區 $buffer
。
use strict ;
use warnings ;
use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
use IO::File ;
my $input = IO::File->new( "<file1.zip" )
or die "Cannot open 'file1.zip': $!\n" ;
my $buffer ;
unzip $input => \$buffer
or die "unzip failed: $UnzipError\n";
IO::Uncompress::Unzip 的建構函式格式如下所示
my $z = IO::Uncompress::Unzip->new( $input [OPTS] )
or die "IO::Uncompress::Unzip failed: $UnzipError\n";
成功時傳回 IO::Uncompress::Unzip
物件,失敗時傳回未定義。失敗時,變數 $UnzipError
會包含錯誤訊息。
如果您執行 Perl 5.005 或更新版本,從 IO::Uncompress::Unzip 傳回的物件 $z
可以完全像 IO::File 檔案控制代碼一樣使用。這表示所有正常的輸入檔案操作都可以使用 $z
執行。例如,若要從壓縮檔案/緩衝區讀取一行,您可以使用下列任一種形式
$line = $z->getline();
$line = <$z>;
強制參數 $input
用來判斷壓縮資料的來源。此參數可以採取下列三種形式之一。
如果 $input
參數是純量,則假設為檔案名稱。此檔案將開啟以供讀取,且壓縮資料將從其中讀取。
如果 $input
參數是檔案控制代碼,則壓縮資料將從其中讀取。字串 '-' 可用作標準輸入的別名。
如果 $input
是純量參照,則壓縮資料將從 $$input
讀取。
下列定義的選項名稱不分大小寫,且可以選擇性地加上前置字元「-」。因此,下列所有選項都是有效的
-AutoClose
-autoclose
AUTOCLOSE
autoclose
OPTS 是下列選項的組合
Name => "membername"
從 zip 檔案開啟「membername」以供讀取。
Efs => 0| 1
當此選項設為 true,且正在讀取的 zip 檔案設定了「語言編碼標記」(EFS) 時,假設成員名稱以 UTF-8 編碼。
如果此選項為 true 時,zip 檔案中的成員名稱不是有效的 UTF-8,則腳本將會顯示錯誤訊息並終止。
請注意,此選項僅適用於 Perl 5.8.4 或更新版本。
此選項預設為 false。
AutoClose => 0|1
此選項僅在 $input
參數是檔案控制代碼時有效。如果指定,且值為 true,則在呼叫 close
方法或銷毀 IO::Uncompress::Unzip 物件後,檔案將關閉。
此參數預設為 0。
MultiStream => 0|1
將完整的 zip 檔案/緩衝區視為單一壓縮資料串流。在多串流模式中讀取時,zip 檔案/緩衝區的每個成員將依序解壓縮,直到遇到檔案/緩衝區的結尾。
此參數預設為 0。
Prime => $string
此選項會在處理輸入檔案/緩衝區之前,先解壓縮 $string
的內容。
當壓縮資料嵌入在其他檔案/資料結構中,且無法在不讀取前幾個位元組的情況下找出壓縮資料的開頭時,此選項會很有用。如果發生這種情況,可以使用此選項,用這些位元組對解壓縮進行「預處理」。
Transparent => 0|1
如果設定此選項,且輸入檔案/緩衝區不是壓縮資料,模組仍會允許讀取它。
此外,如果輸入檔案/緩衝區確實包含壓縮資料,且緊接著有未壓縮資料,設定此選項會讓此模組將整個檔案/緩衝區視為單一資料串流。
此選項預設為 1。
BlockSize => $num
在讀取壓縮輸入資料時,IO::Uncompress::Unzip 會以 $num
位元組的區塊讀取資料。
此選項預設為 4096。
InputLength => $size
如果存在此選項,將會限制從輸入檔案/緩衝區讀取的壓縮位元組數目為 $size
。可以在壓縮資料串流後方有有用資料,且您事先知道壓縮資料串流的確切長度的這種情況下,使用此選項。
此選項大多在從檔案控制代碼讀取時使用,這種情況下,檔案指標會留在壓縮資料串流後方的第一個位元組。
此選項預設為關閉。
Append => 0|1
此選項控制 read
方法對未壓縮資料的處理方式。
如果設定為 1,所有未壓縮資料都將附加到 read
方法的輸出參數。
如果設定為 0,read
方法的輸出參數內容將被未壓縮資料覆寫。
預設為 0。
Strict => 0|1
此選項控制在執行解壓縮時是否使用下方定義的額外檢查。當 Strict 處於開啟狀態時,會執行額外測試,當 Strict 處於關閉狀態時,則不會執行。
此選項的預設值為關閉。
待辦事項
用法為
$status = $z->read($buffer)
讀取一區塊壓縮資料(壓縮區塊的大小由建構函數中的 Buffer
選項決定),解壓縮資料,並將任何未壓縮資料寫入 $buffer
。如果在建構函數中設定 Append
參數,未壓縮資料將附加到 $buffer
參數。否則,將覆寫 $buffer
。
傳回寫入 $buffer
的未壓縮位元組數目,如果為檔案結束或發生錯誤,則傳回零或負數。
用法為
$status = $z->read($buffer, $length)
$status = $z->read($buffer, $length, $offset)
$status = read($z, $buffer, $length)
$status = read($z, $buffer, $length, $offset)
嘗試將 $length
位元組的未壓縮資料讀入 $buffer
。
此 read
方法形式與前一個方法形式的主要差異在於,此方法將嘗試傳回 完全 $length
位元組。此函數不會執行的唯一情況是遇到檔案結束或 I/O 錯誤。
傳回寫入 $buffer
的未壓縮位元組數目,如果為檔案結束或發生錯誤,則傳回零或負數。
用法為
$line = $z->getline()
$line = <$z>
讀取單一行。
此方法完全支援使用變數 $/
(或在使用 English
時使用 $INPUT_RECORD_SEPARATOR
或 $RS
)來決定什麼構成行尾。段落模式、記錄模式和檔案 slurp 模式都受支援。
用法為
$char = $z->getc()
讀取單一字元。
用法為
$char = $z->ungetc($string)
用法為
$status = $z->inflateSync()
待辦事項
用法為
$hdr = $z->getHeaderInfo();
@hdrs = $z->getHeaderInfo();
此方法傳回一個雜湊參考(在純量內容中)或一個清單或雜湊參考(在陣列內容中),其中包含壓縮資料串流中每個標頭欄位的資訊。
用法為
$z->tell()
tell $z
傳回未壓縮的檔案偏移量。
用法為
$z->eof();
eof($z);
如果已到達壓縮輸入串流的結尾,則傳回 true。
$z->seek($position, $whence);
seek($z, $position, $whence);
提供 seek
功能的子集,但限制為只能在輸入檔案/緩衝區中向前搜尋。嘗試向後搜尋會造成致命錯誤。
請注意,此模組中 seek
的實作並未提供對壓縮檔案/緩衝區的真正隨機存取。其運作方式是從檔案/緩衝區中的目前偏移量開始解壓縮資料,直到它到達 seek
參數中指定的未壓縮偏移量。對於非常小的檔案,這可能是可接受的行為。對於大型檔案,它可能會造成無法接受的延遲。
$whence
參數採用一個常用值,即 SEEK_SET、SEEK_CUR 或 SEEK_END。
成功傳回 1,失敗傳回 0。
用法為
$z->binmode
binmode $z ;
這是一個為完整性而提供的空操作。
$z->opened()
如果物件目前參照開啟的檔案/緩衝區,則傳回 true。
my $prev = $z->autoflush()
my $prev = $z->autoflush(EXPR)
如果 $z
物件與檔案或檔案句柄關聯,則此方法會傳回底層檔案句柄目前的自動快取設定。如果 EXPR
存在且非零,則它會在每次寫入/列印操作後啟用快取。
如果 $z
與緩衝區關聯,則此方法沒有作用,且總是傳回 undef
。
請注意,特殊變數 $|
無法用於設定或擷取自動快取設定。
$z->input_line_number()
$z->input_line_number(EXPR)
傳回目前的未壓縮行號。如果 EXPR
存在,則它具有設定行號的效果。請注意,設定行號不會變更正在讀取的檔案/緩衝區中的目前位置。
$/
的內容用於判定什麼構成行終止符。
$z->fileno()
fileno($z)
如果 $z
物件與檔案或檔案句柄關聯,則 fileno
會傳回底層檔案描述符。一旦呼叫 close
方法,fileno
會傳回 undef
。
如果 $z
物件與緩衝區關聯,則此方法會傳回 undef
。
$z->close() ;
close $z ;
關閉輸出檔案/緩衝區。
對於大多數版本的 Perl,如果 IO::Uncompress::Unzip 物件被銷毀(明確地或透過參照物件的變數超出範圍),則此方法會自動呼叫。例外情況是 Perl 版本 5.005 至 5.00504 和 5.8.0。在這些情況下,close
方法會自動呼叫,但直到程式終止時所有現存物件的整體銷毀為止。
因此,如果您希望您的指令碼能夠在所有版本的 Perl 上執行,您應該明確呼叫 close
,而不依賴自動關閉。
成功時傳回 true,否則傳回 0。
如果在建立 IO::Uncompress::Unzip 物件時已啟用 AutoClose
選項,且該物件與檔案相關聯,則也會關閉底層檔案。
用法為
my $status = $z->nextStream();
跳到輸入檔案/緩衝區中的下一個壓縮資料串流。如果找到新的壓縮資料串流,則會清除 eof 標記,且 $.
會重設為 0。
如果在 zip 檔案後方有尾隨資料,且已啟用 Transparent
選項,則此方法會將該尾隨資料視為 zip 檔案的另一個成員。
如果找到新的串流,則傳回 1;如果未找到,則傳回 0;如果遇到錯誤,則傳回 -1。
用法為
my $data = $z->trailingData();
在解壓縮完成後,傳回壓縮資料串流後方(如果有)的資料。只有在遇到壓縮資料串流的結尾後,呼叫此方法才有意義。
當壓縮資料串流後緊接著有有用的資訊,而且您不知道壓縮資料串流的長度時,可以使用此選項。
如果輸入為緩衝區,trailingData
將傳回從壓縮資料串流的結尾到緩衝區結尾的所有內容。
如果輸入為檔案句柄,trailingData
將傳回壓縮資料串流的結尾到達後,檔案句柄輸入緩衝區中剩下的資料。然後,您可以使用檔案句柄讀取輸入檔案的其餘部分。
如果輸入為檔案名稱,請不要費心使用 trailingData
。
如果您在開始解壓縮之前知道壓縮資料串流的長度,則可以透過在建構函式中設定 InputLength
選項,來避免使用 trailingData
。
目前 IO::Uncompress::Unzip 不需要任何符號常數。
匯入 unzip
和 $UnzipError
。與執行以下動作相同
use IO::Uncompress::Unzip qw(unzip $UnzipError) ;
以下程式碼可用於一次瀏覽一個壓縮資料串流的 zip 檔案。
use IO::Uncompress::Unzip qw($UnzipError);
my $zipfile = "somefile.zip";
my $u = IO::Uncompress::Unzip->new( $zipfile )
or die "Cannot open $zipfile: $UnzipError";
my $status;
for ($status = 1; $status > 0; $status = $u->nextStream())
{
my $name = $u->getHeaderInfo()->{Name};
warn "Processing member $name\n" ;
my $buff;
while (($status = $u->read($buff)) > 0) {
# Do something here
}
last if $status < 0;
}
die "Error processing $zipfile: $!\n"
if $status < 0 ;
會讀取每個個別壓縮資料串流,直到到達邏輯檔案結尾。然後呼叫 nextStream
。這會跳到下一個壓縮資料串流的開頭,並清除檔案結尾旗標。
另外值得注意的是,nextStream
可以隨時呼叫,您不必等到耗盡壓縮資料串流後才跳到下一個串流。
Daniel S. Sterling 編寫了一個腳本,使用 IO::Uncompress::UnZip
讀取 zip 檔案,並將其內容解壓縮到磁碟。
此腳本可從 https://gist.github.com/eqhmcow/5389877 取得。
一般回饋/問題/錯誤報告應傳送至 https://github.com/pmqs/IO-Compress/issues(優先)或 https://rt.cpan.org/Public/Dist/Display.html?Name=IO-Compress。
Compress::Zlib、IO::Compress::Gzip、IO::Uncompress::Gunzip、IO::Compress::Deflate、IO::Uncompress::Inflate、IO::Compress::RawDeflate、IO::Uncompress::RawInflate、IO::Compress::Bzip2、IO::Uncompress::Bunzip2、IO::Compress::Lzma、IO::Uncompress::UnLzma、IO::Compress::Xz、IO::Uncompress::UnXz、IO::Compress::Lzip、IO::Uncompress::UnLzip、IO::Compress::Lzop、IO::Uncompress::UnLzop、IO::Compress::Lzf、IO::Uncompress::UnLzf、IO::Compress::Zstd、IO::Uncompress::UnZstd、IO::Uncompress::AnyInflate、IO::Uncompress::AnyUncompress
File::GlobMapper、Archive::Zip、Archive::Tar、IO::Zlib
有關 RFC 1950、1951 和 1952,請參閱 https://datatracker.ietf.org/doc/html/rfc1950、https://datatracker.ietf.org/doc/html/rfc1951 和 https://datatracker.ietf.org/doc/html/rfc1952
zlib 壓縮函式庫是由 Jean-loup Gailly gzip@prep.ai.mit.edu
和 Mark Adler madler@alumni.caltech.edu
編寫的。
zlib 壓縮函式庫的主要網站為 http://www.zlib.org。
zlib-ng 壓縮函式庫的主要網站為 https://github.com/zlib-ng/zlib-ng。
gzip 的主要網站為 http://www.gzip.org。
此模組是由 Paul Marquess 編寫的,pmqs@cpan.org
。
請參閱 Changes 檔案。
版權所有 (c) 2005-2023 Paul Marquess。保留所有權利。
此程式為免費軟體;您可以在與 Perl 相同的條款下重新散布或修改它。