|
|
Classification: |
C++ |
Category: |
Application Engines |
Created: |
01/07/2003 |
Modified: |
01/13/2003 |
Number: |
FAQ-0844 |
Platform: |
Symbian OS v7.0 |
|
Question: What support does Symbian OS provide for compressing and decompressing files?
Answer: Support is available from Symbian OS v7.0 for decompression of zip files based on a version of the zlib utility. This is accessible
through CZipFile and related classes. Although zlib also supports compression, Symbian OS does not provide the necessary extensions to create
zip files of the compressed data. The following code finds compressed zip files in a folder c:\test\zip and unzips their contents into a c:\test\zip\extracts.
Each zip file is unzipped into a subfolder named after the file itself. Note that zip-related errors and other enums are defined
in ziparchive.h.
#include
_LIT(KExtractZipPath, "C:\\test\\zip\\extracts\\"); _LIT(KPath, "C:\\test\\zip\\");
void UnzipFileL(RFs& aFs, TFileName* aFileName); void ExtractFileL(RFs& aFs, CZipFileMember* aMember, CZipFile* aZipFile, TFileName* aFileName);void DoUnzipL(){ RFs fs; User::LeaveIfError(fs.Connect()); //Connect to file session User::LeaveIfError(fs.SetSessionPath(KPath)); //Set Session Path to directory containing test zip files CleanupClosePushL(fs); TFileName path; CDir* fileList; User::LeaveIfError(fs.GetDir(path, KEntryAttNormal, ESortByName, fileList)); //Get list of files to unzip CleanupStack::PushL(fileList); for (TInt y = 0; y < fileList->Count(); y++){ TFileName dirFileName((*fileList)[y].iName); UnzipFileL(fs, &dirFileName); }CleanupStack::PopAndDestroy(2); }
void UnzipFileL(RFs& aFs, TFileName* aFileName){ CZipFile* zipFile; CZipFileMember* member; CZipFileMemberIterator* fileMembers; zipFile = CZipFile::NewL(aFs,*aFileName); CleanupStack::PushL(zipFile); User::LeaveIfError(zipFile->OpenL()); fileMembers = zipFile->GetMembersL(); CleanupStack::PushL(fileMembers); while (member = fileMembers->NextL()){ //You must take ownership of the member object created for you by NextL()! CleanupStack::PushL(member); ExtractFileL(aFs, member, zipFile, aFileName); aFs.SetSessionPath(KPath); CleanupStack::PopAndDestroy(); //member }CleanupStack::PopAndDestroy(2); //fileMembers, zipFile } void ExtractFileL(RFs& aFs, CZipFileMember* aMember, CZipFile* aZipFile, TFileName* aFileName){ TInt loop=0; HBufC* name = aMember->Name()->AllocLC(); // Change any instances of '/' to '\' in zipped file paths while (loop < name->Length()){ if ((*name)[loop] == '/'){ name->Des()[loop] = '\\'; }loop++; }TFileName fn; fn.Append(KExtractZipPath); fn.Append(*aFileName); fn.Append('\\'); fn.Append(*name); User::LeaveIfError(aFs.SetSessionPath(KExtractZipPath)); TInt err = aFs.MkDirAll(fn)); if (err != KErrNone && err != KErrAlreadyExists){ User::Leave(err); }RFile expandedMember; User::LeaveIfError(expandedMember.Replace(aFs, fn, EFileShareAny|EFileWrite)); CleanupClosePushL(expandedMember);
RZipFileMemberReaderStream* fileStream;
// KCompressionMethodNotSupported is possible in decompressing file here
User::LeaveIfError(aZipFile->GetInputStreamL(aMember, fileStream)); CleanupStack::PushL(fileStream);
// Assume file contents are 8-bit data TUint32 size = aMember->UncompressedSize(); HBufC8* bytes = HBufC8::NewLC(size); TPtr8 ptr = bytes->Des(); //Obtain a modifiable descriptor fileStream->Read(ptr, size); //Later versions of Symbian use ReadL() instead here // save the unzipped contents to file User::LeaveIfError(expandedMember.Write(ptr)); CleanupStack::PopAndDestroy(4); //bytes, fileStream, expandedMember, name }
|
|
|