Decompressing File Archives

The Zip Compression Library, EZLib provides file archive decompression functionality for the Symbian platforms.

EZLib allows clients to decompress data from file archives. The decompression task is performed by calling the decompression functions iteratively, until the required task completion.

Context

The input archive file is opened and the properties of all the files in the archive are retrieved.

Steps

  1. Pass the input file archive and create an instance of the CZipFile class. The CZipFile is a read only interface. It does not support file compression to a single or multiple zip file archives.
  2. Invoke CZipFile::GetMembersL() that returns a pointer of CZipFileMemberIterator The CZipFileMemberIterator iterator class provides functions that point to the first file in the archive and to navigate through all the entries in the archive. The CZipFileMemberIterator iterator class can access each member of the zip archive using CZipFileMemberIterator::NextL()
  3. The properties of the member file are retrieved using the functions of CZipFileMember. The CZipFileMember class retrieves the properties of the member file once the member file is accessible.
  4. The files extracted from the archive are stored in the output folder. If the output folder is unavailable a new folder is created prior to archive decompression.

Example

The following example code illustrates the decompression of file archive.

/*
    * Decompresses all the files in "inputarchive.zip" using the EZlib.
    *  If an input filename is not specified it is assumed that the
    * input file name is contained in a provided .ini file.
    */
    void CEZlibEZipTests::DoEZlibZipArchiveDecompressL()
    {
    RFs iFs;
    iFS.connect();
    CleanupClosePushL(iFS);
    TInt err = KErrNone;
    HBufC8 *outputBuffer = HBufC8::NewLC(outputBufferSize);

    _LIT(KInputFileLocation, "c:\\private\\E80000B7\\zip\\input\\inputarchive.zip");
    TFileName inputFile(KInputFileLocation);

    RFile input;
    err = input.Open(iFs, inputFile, EFileStream | EFileRead | EFileShareExclusive);
    if(err != KErrNone)
        {
        INFO_PRINTF1(KOpenFileError);
        User::Leave(err);
        }
    CleanupClosePushL(input);

    CZipFile *zipFile = CZipFile::NewL(iFs,input);
    CleanupStack::PushL(zipFile);
    CZipFileMemberIterator *fileMemberIter = zipFile->GetMembersL();

    //  iZipArchiveEzlibFolder = GenerateZipArchiveFolderNameL(aInputFileName);
    //  iZipArchiveEzlibFolder.Append(KZipArchiveEzlib);

    for(TOLDEZIP::CZipFileMember *fileMember = fileMemberIter->NextL(); fileMember != NULL; fileMember = fileMemberIter->NextL())
        {
        TFileName tmpfilename(*(fileMember->Name()));

        // Check if we have a folder or file
        TPtrC lastChar = tmpfilename.Right(1);
        if(lastChar.Compare(_L("\\")) != 0 && lastChar.Compare(_L("/")) != 0)
            {
            RFile output;
            err = output.Replace(iFs, tmpfilename, EFileStream | EFileWrite | EFileShareExclusive);
            if(err != KErrNone)
                {
                INFO_PRINTF1(KCreateFileError);
                User::Leave(err);
                }
            CleanupClosePushL(output);

            TOLDEZIP::RZipFileMemberReaderStream *readerStream;
            zipFile->GetInputStreamL(fileMember, readerStream);
            CleanupStack::PushL(readerStream);

            TPtr8 pOutputBuffer = outputBuffer->Des();
            do
                {
                err = readerStream->Read(pOutputBuffer, outputBufferSize);
                output.Write(pOutputBuffer);
                } while(err == KErrNone);
            if(err != KErrEof)
                {
                User::Leave(err);
                }
            CleanupStack::PopAndDestroy(2);
            }
        else
            {
            TFileName fullPath("c:\\private\\E80000B7\\zip\\input\\");
            fullPath.Append(tmpfilename);
            iRfs.MkDir(fullPath);
            }
        }
    CleanupStack::PopAndDestroy(3);
    }