在Symbian OS中讀取ZIP文件

Symbian OS中讀取ZIP文件

 

 

 

    [ 原著:Antony Pranata http://www.antonypranata.com ]

          [譯:Beover1984 [email protected]]

如今最普遍的壓縮文件格式就要算ZIP了,它最開始是Phil Katz借鑑ARC格式創建的。Symbian OS提供了一個名爲CzipFile的類來讀取ZIP文件,它從Symbian 7.X開始被支持。這篇文章將告訴你如何使用CzipFile並給出一個例子。你可以在Series 60 2.x or UIQ 2.x環境下編譯,運行這個例子。

 

 

 

雖然SDK文檔中有CzipFile的介紹,但還是遠遠不夠的,並且沒有例子告訴你如何使用它,這也是我寫這篇文章的原因。希望它對你有所幫助。

 

 

 

 

 

 

 

一、讀取ZIP文件

 

 

 

我們以一種簡單的情況開始:打開ZIP文件並顯示其內部所有文件的信息。首先,我們需要創建一個新的CzipFile 實例。下面是你可以使用的已封裝好的兩階段構造函數:

 

 

 

 

 

 

 

CZipFile* zipFile = CZipFile::NewL(fileSession, aCompressedFile);

 

 

 

CleanupStack::PushL(zipFile);

 

 

 

 

 

 

 

 

構造函數的第一個參數是文件服務器的會話,第二個參數是ZIP文件的名字。

 

 

 

下面,我們要得到ZIP文件的迭代器(iterator)來遍歷其中的文件,可以通過調用CZipFile::GetMembersL()實現,它返回一個CzipFileMemberIterator類的實例。

 

 

 

 

 

 

 

CZipFileMemberIterator* members = zipFile->GetMembersL();

 

 

 

CleanupStack::PushL(members);

 

 

 

 

 

 

 

注意member的所有權已傳遞到調用者,因此我們在使用完之後需要刪除它。

 

 

 

現在,我們怎麼得到每一個文件的實例呢?可以調用CZipFileMemberIterator::NextL()進行遍歷直到它返回0爲止(返回0意爲着沒有文件了)。看下面的代碼:

 

 

 

 

 

 

 

CZipFileMember* member;

 

 

 

while ((member = members->NextL()) != 0)

 

 

 

{

 

 

 

console->Printf(

 

 

 

                   KInfoMessage,

 

 

 

                   member->Name(),

 

 

 

                   member->CompressedSize(), member->UncompressedSize());       

 

 

 

delete member;

 

 

 

}

 

 

 

 

 

 

 

上面的代碼打印了ZIP文件中所有文件的名字,壓縮後的大小和未壓縮的大小。再次注意我們需要刪除member,因爲我們已經是它的擁有者了。

 

 

 

最後,別忘了釋放我們分配的任何資源:

 

 

 

 

 

 

 

CleanupStack::PopAndDestroy(); // members

 

 

 

CleanupStack::PopAndDestroy(); // zipFile

 

 

 

 

 

 

 

如果我們有一個含有3個文件的ZIP文件,例如:Example.txt, Example.dat and Example.png程序的輸出就像下面這樣(你可以在文章的最後下載這個例子):

 

 

 

 

 

 

 

Example.txt - 11 - 11

 

 

 

Example.dat - 15 - 180

 

 

 

Example.png - 4393 – 4393

 

 

 

 

 

 

 

二、從ZIP文件中提取文件

 

 

 

這段將展示如何從ZIP文件中提取文件。和前面的例子一樣,第一步需要創建CzipFile的實例:

 

 

 

 

 

 

 

CZipFile* zipFile = CZipFile::NewL(fileSession, aCompressedFile);

 

 

 

CleanupStack::PushL(zipFile);

 

 

 

 

 

 

 

這裏我們不再需要一個迭代器,因爲我們對一個指定的文件感興趣,需要調用的方法是CZipFile::CaseInsensitiveMemberL()。這個方法需要一個你想訪問文件的名字做爲參數:

 

 

 

 

 

 

 

CZipFileMember* member = zipFile->CaseInsensitiveMemberL(aFileName);

 

 

 

CleanupStack::PushL(member);

 

 

 

 

 

 

 

下面這步將得到輸入流並使用Read()方法提取文件,ZIP文件中的文件輸入流使用RzipFileMemberReaderStream類,得到輸入流的方法是調用CZipFile::GetInputStreamL()

 

 

 

 

 

 

 

RZipFileMemberReaderStream* stream;

 

 

 

zipFile->GetInputStreamL(member, stream);

 

 

 

CleanupStack::PushL(stream);

 

 

 

 

 

 

 

下面的代碼展示如何讀取文件,在讀文件之前,代碼分配了一個文件未壓縮大小的buffermember->UncompressesedSize() )用來存儲文件。

 

 

 

 

 

 

 

HBufC8* buffer = HBufC8::NewLC(member->UncompressedSize());

 

 

 

TPtr8 bufferPtr(buffer->Des());

 

 

 

User::LeaveIfError(stream->Read(bufferPtr, member->UncompressedSize()));

 

 

 

 

 

 

 

如果你的文件很大,不要像上面那樣通過一次Read()讀取所有數據,它會阻塞你的程序。可以通過一個活動對象一塊塊的讀取數據代替上面的方法。例子中使用一次Read()只是爲了演示的簡單性。

 

 

 

現在我們把文件讀到了一個buffer中,你可以立刻使用它,或者選擇以文件的形式保存。下面的代碼把它保存到文件:

 

 

 

 

 

 

 

RFile file;

 

 

 

User::LeaveIfError(file.Replace(fileSession, fileName, EFileWrite));

 

 

 

CleanupClosePushL(file);

 

 

 

User::LeaveIfError(file.Write(*buffer));

 

 

 

fileSession.Close();

 

 

 

 

 

 

 

最後,別忘了釋放所有分配的資源:

 

 

 

 

 

 

 

CleanupStack::PopAndDestroy(5); // file, buffer, stream, member, zipFile

 

 

 

 

 

 

 

三、例子

 

 

 

例子完成兩件事:

 

 

 

1. 顯示Example.zip文件中所有的文件的信息。它在IteratorExampleL()函數中實現。

 

 

 

2. Example.zip提取Example.txt並保存到設備的c:/data/Example.txt。它在ExtractionExampleL()函數中實現。

 

 

 

 

 

 

 

下載地址:

 

 

 

http://www.antonypranata.com/articles/download/ZipExample.zip

 

 

 

http://www.newlc.com/IMG/zip/ZipExample.zip

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發佈了20 篇原創文章 · 獲贊 3 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章