Reading ZIP File in Symbian OS
15 Oct 2005 - 10:14

The most popular archive file format used these days is ZIP, originally created by Phil Katz from the modification of ARC format. Symbian OS provides a class, called CZipFile, to read ZIP file. This class is supported by Symbian since version 7.x. This article will show how to use CZipFile and give an example. You can compile and run the example in Series 60 2.x or UIQ 2.x.

Although CZipFile is documented in Symbian SDKs, the explanation is far from enough. Another challenge, there is no example how to use the class. That's why I write this article to share my experience reading ZIP file in Symbian OS. I hope this would be useful for you.

Reading ZIP File

Let's start with a simple case, open a ZIP file and display information of all the files inside the ZIP file. Firstly, we need to create a new instance of CZipFile. There is a two-phase constructor that you can use to create it.

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

The first parameter of the constructor is a session of File Server. The second parameter is the file name of the ZIP file.

Next, we have to get the iterator for the ZIP file to iterate all the files one by one. It can be done by calling CZipFile::GetMembersL(). The return value is an instance of CZipFileMemberIterator class.

CZipFileMemberIterator* members = zipFile->GetMembersL();
CleanupStack::PushL(members);

Note that the ownership of members will be passed to the caller, thus we have to delete it after we are done.

Now, how can we get the instance of each file? By calling CZipFileMemberIterator::NextL(). We have to call this method until it returns 0, which means there is no more file. Look at the following example:

CZipFileMember* member;
while ((member = members->NextL()) != 0)
        {
        console->Printf(
                KInfoMessage,
                member->Name(),
                member->CompressedSize(), member->UncompressedSize());       
        delete member;
        }

The example above prints the name, compressed size and uncompressed size of all the files in the ZIP file. Note that we have to delete member because the ownership is passed to caller.

Finally, don't forget to release all the resources that we have allocated.

CleanupStack::PopAndDestroy(); // members
CleanupStack::PopAndDestroy(); // zipFile

If we have a ZIP file that contains three file, i.e. Example.txt, Example.dat and Example.png, the output will look like this (you can download this ZIP file at the end of this article).

Example.txt - 11 - 11
Example.dat - 15 - 180
Example.png - 4393 - 4393

Extracting a File from ZIP File

This section shows how to extract a specific file from a ZIP file. As the previous example, the first step is to create the instance of CZipFile.

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

Here, we don't need an iterator because we are interested only in a specific file. The method that we have to call to get the instance of it is CZipFile::CaseInsensitiveMemberL(). This method requires a parameter, that is the file name that you want to access.

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

Once again, we have to delete member after we have finished using it. The next step is to the input stream and use the Read() method to extract the file. The input stream of a file inside ZIP file is RZipFileMemberReaderStream. The method used to get the input stream is CZipFile::GetInputStreamL().

RZipFileMemberReaderStream* stream;
zipFile->GetInputStreamL(member, stream);
CleanupStack::PushL(stream);

The following code shows how to read the file. Before reading the file, the code allocates a buffer to store with the size of member->UncompressesedSize().

HBufC8* buffer = HBufC8::NewLC(member->UncompressedSize());
TPtr8 bufferPtr(buffer->Des());
User::LeaveIfError(stream->Read(bufferPtr, member->UncompressedSize()));

If your file is quite huge, do not use "one-shot" Read() like the example above. It is not good because it will block your program. Instead, read using a small block of buffer and do it inside an active object. This example use "one-shot" Read() for simplicity reason.

Now we have the extracted file in a buffer. You can use it right away, or alternatively you can write it to a file. Here is the example how to write it to a file.

RFile file;
User::LeaveIfError(file.Replace(fileSession, fileName, EFileWrite));
CleanupClosePushL(file);
User::LeaveIfError(file.Write(*buffer));

Finally, do not forget to release all the allocated resources.

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

Example

The following file contains the complete source code of the two examples above. This example is a console program. The output of the compiled example is a standalone .exe file, ZipExample.exe. Copy this file to your device at c:\systems\programs or any other directories. Before running the example, make sure that you have copied \group\Example.zip to c:\data\Example.zip on your device too.

The example does two things, i.e.:
-  Display information of all the files contained in c:\data\Example.zip. It is done in IteratorExampleL() function.
-  Extract Example.txt from c:\data\Example.zip and save it to c:\data\Example.txt. It is done in ExtractionExampleL() function.

ZipExample.zip
ZipExample.zip

Further Reading

-  .ZIP File Format Specification - specification from the creator of PKZIP, the first program that supports ZIP file.
-  CZipFile - official documentation of class CZipFile from Symbian web site.

Tutorial posted October 15th, 2005 by antonypranata

Submitted by Beover1984 (not verified) on Fri, 2005-12-02 04:28.

Thank you for your article!

I have translated it into chinese that is useful for more people.


Submitted by Antony Pranata (not verified) on Tue, 2005-12-20 16:02.

Sorry, where did you publish your translation? Did you submit it to NewLC.com too?

Antony


Submitted by Beover1984 (not verified) on Thu, 2006-03-16 06:38.

I posted it on Forum Nokia, you can see it at http://discussion.forum.nokia.com/forum/showthread.php?t=70826 Thanks again.

Submitted by Anonymous on Tue, 2006-04-11 13:42.

Thanks for the article ;) Do you know what the the OpenL() method is there for ?

Submitted by daz (not verified) on Tue, 2006-04-11 13:44.

Thanks for the article ;) Do you know what the the OpenL() method is there for ?

Submitted by Antony Pranata (not verified) on Wed, 2006-04-12 03:35.

The OpenL() method has been deprecated since Symbian 7.0.

Submitted by Anonymous on Wed, 2006-05-24 10:29.

Thanks for this very helpful article. I have used these classes successfully on S60, S80, S60 3rd Edition. However, on UIQ I get the following issues:

It works fine on the emulator, but on the device I got the following results:

P900 : the RZipFileMemberReaderStream::Read() method returns an error code of -9353676, but the file unzips correctly if this error is ignored.

P800 : It doesn't seem to work at all, no errors, no result. Are these classes supported on this device (its platform) ?


Submitted by Anonymous on Mon, 2006-07-03 10:08.

I too get the problem that you describe on the P910i (ie the RZipFileMemberReaderStream::Read() returns a non-system error but if ignored the fuctionality is correct).

Does anyone have an explanation for this? Is it a bug on this class? Can we get word to Symbian to fix it if it is?


Submitted by Vinayaka Karjigi (not verified) on Fri, 2006-12-29 09:47.

Hi ,

Can I know how to implement in Read() in

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

as the RZipFileMemberReaderStream class doesnt give any asychronous call to read function.

I am having a buffer to read instead of a file and i need a asychronous function to read so that i can read without blocking

can anybody help me


Submitted by zlatan24 on Fri, 2007-10-26 18:53.

On this OS next tool possible don't may help, but try - Fix zip file, know how restore ZIP files from damaged media (floppy disks, CDs, DVDs, Zip drives, etc,,,, .)
allows the program to minimize data loss during zip recovery, therefore the user sees as much as possible about the files being recovered, program supports Windows 98, Windows Me, Windows NT 4.0, Windows 2000, Windows XP, Windows XP SP2, Windows 2003 and Windows Vista, repair ZIP files larger than 2 GB.


Submitted by zlatan24 on Fri, 2008-05-09 10:14.

Use-damaged zip files,program supports Windows 98, Windows Me, Windows NT 4.0, Windows 2000, Windows XP, Windows XP SP2, Windows 2003 and Windows Vista,help users solve the zip recovery issues and always have control of their archived data,recovers information from damaged zip files and minimizes data loss during the zip recovery process,application is the fact that it employs several heuristic algorithms and methods to repair zip file or recover information from damaged zip files.



copyright 2003-2009 NewLC SARL