ByteArray 示例 讀取 zip 檔案

2021-06-07 01:55:40 字數 4105 閱讀 3928

原文

本示例中所編寫的**僅用於分析不包含資料夾且不需要資料描述符記錄的 zip 檔案。它將忽略最後乙個檔案的資料後面的所有資訊。

每個檔案的檔案標頭的格式如下:

檔案標頭簽名

4 位元組

所需版本

2 位元組

一般用途位標記

2 位元組

壓縮方法

2 位元組 (8=deflate; 0=uncompressed)

檔案的最後修改時間

2 位元組

檔案的最後修改日期

2 位元組

crc-32

4 位元組

壓縮後的大小

4 位元組

解壓縮後的大小

4 位元組

檔名長度

2 位元組

額外字段長度

2 位元組

檔名變數

額外字段變數

檔案標頭的後面是實際的檔案資料,既可以是壓縮後的也可以是解壓縮後的檔案資料,具體取決於壓縮方法標誌。如果檔案資料為解壓縮後的資料,則此標誌為 0;如果該資料為使用 deflate 演算法壓縮的資料,則為 8;如果採用的是其他壓縮演算法,則為其他值。

該示例的使用者介面由乙個標籤和乙個文字區域 (tafiles) 組成。該應用程式將它在 zip 檔案中遇到的各檔案的以下資訊寫入文字區域:檔名、壓縮後的大小和解壓縮後的大小。以下 mxml 文件為應用程式的 flex 版本定義使用者介面:

<?xml version="1.0" encoding="utf-8"?> 

]]>

程式開頭將執行以下任務:

// for flex

private function init():void

**的下一部分將在偏移量為 8 處讀取標頭位元組並將值儲存在變數 compmethod 中。該位元組包含指示壓縮此檔案時所用壓縮方法的值。允許使用多種壓縮方法,但實際上幾乎所有 .zip 檔案均使用 deflate 壓縮演算法。如果當前檔案以 deflate 壓縮方式進行壓縮,則 compmethod 為 8;如果檔案未壓縮,則 compmethod 為 0。

bytes.position = 8; 

compmethod = bytes.readbyte(); // store compression method (8 == deflate)

位於前 30 個位元組之後的部分是標頭的可變長度部分,包含了檔名並可能包含額外字段。變數 offset 用於儲存此部分的大小。該大小的計算方式為將檔名長度和額外字段長度相加,這兩個長度可分別從標頭中偏移量為 26 和 28 的位置讀取。

offset = 0;    // stores length of variable portion of metadata  

bytes.position = 26; // offset to file name length

flnamelength = bytes.readshort(); // store file name

offset += flnamelength; // add length of file name

bytes.position = 28; // offset to extra field length

xfldlength = bytes.readshort();

offset += xfldlength; // add length of extra field

接下來程式將讀取檔案標頭的可變長度部分,以將該部分的位元組數儲存在 offset 變數中。

// read variable length bytes between fixed-length header and compressed file data 

zstream.readbytes(bytes, 30, offset);

程式將從標頭的可變長度部分中讀取檔名並在文字區域中顯示它,同時顯示檔案壓縮後(已壓縮)及解壓縮後(原始)大小。

// flash version 

bytes.position = 30;

filename = bytes.readutfbytes(flnamelength); // read file name

bytes.position = 18;

compsize = bytes.readunsignedint(); // store size of compressed portion

bytes.position = 22; // offset to uncompressed size

uncompsize = bytes.readunsignedint(); // store uncompressed size

// flex version 

bytes.position = 30;

filename = bytes.readutfbytes(flnamelength); // read file name

tafiles.text += filename + "\n"; // write file name to text area

bytes.position = 18;

compsize = bytes.readunsignedint(); // store size of compressed portion

tafiles.text += "\tcompressed size is: " + compsize + '\n';

bytes.position = 22; // offset to uncompressed size

uncompsize = bytes.readunsignedint(); // store uncompressed size

tafiles.text += "\tuncompressed size is: " + uncompsize + '\n';

該示例從檔案流中將檔案的其餘部分按照壓縮後大小所指定的長度讀入到 bytes 中,同時覆蓋前 30 位元組中的檔案標頭。即使檔案並未壓縮,壓縮後的大小也是精確的,因為在此情況下,壓縮後的大小將等於檔案未壓縮時的大小。

// read compressed file to offset 0 of bytes; for uncompressed files 

// the compressed and uncompressed size is the same

if (compsize == 0) continue;

zstream.readbytes(bytes, 0, compsize);

接下來,示例將對壓縮的檔案進行解壓縮並呼叫 outfile() 函式將檔案寫入輸出檔案流。它將向 outfile() 傳遞檔名和包含檔案資料的位元組陣列。

if (compmethod == 8) // if file is compressed, uncompress 

outfile(filename, bytes); // call outfile() to write out the file

在之前提到的範例中,bytes.uncompress(compressionalgorithm.deflate) 僅在 air 應用程式中有效。要為 air 和 flash player 將壓縮的資料解壓,可呼叫 bytearray 的 inflate() 函式。

右括號指示 while 迴圈、init() 方法以及 flex 應用程式**結束,不過 outfile() 方法除外。執行過程再次返回至 while 迴圈的開始處並繼續處理 .zip 檔案中其餘的位元組:提取另乙個檔案,如果最後乙個檔案已處理完畢,則終止該 .zip 檔案處理。

} // end of while loop 

outfile() 函式將以 write 模式開啟桌面上的輸出檔案,為其指定 filename 引數提供的名稱。然後該函式將把檔案資料從 data 引數中寫入輸出檔案流 (outstream) 並關閉該檔案。

// flash version

function outfile(filename:string, data:bytearray):void

private function outfile(filename:string, data:bytearray):void 

O DIRECT方式讀取檔案示例

include include include include include include include include include 讀檔案類 class cfilereader cfilereader bool open const char filepath 取得檔案大小,以便一次性將...

PHPExcel讀取excel檔案示例

author xiaoqiang.wu version 1.01 error reporting e all date default timezone set asia shanghai phpexcel iofactory require once classes phpexcel iofact...

Julia語言讀取CSV檔案示例一

使用的julia版本為1.1.0 如下 using csv function 你好 return 你好 endprintln this is a demo for read csv file.function 讀取電子 路徑 csv.read 路徑,delim datarow 1 end問候語 你好...