ZipFile Manual

About

The ZipFile class provides means to work with ZIP archives. ZIP files can be created, modified and extracted.

Allocation/Deallocation

ZipFile objects are created with the usual tools, see Entity Creation and Destruction Manual.

Opening and Closing

Filename

Metadata

Compression Level

CRC

Extracting an Entire Archive

// This example demonstrates extracting the selected ZIP file to a given folder.
Filename fnZip, fnDest;
if (!fnZip.FileSelect(FILESELECTTYPE_ANYTHING, FILESELECT_LOAD, "Choose a ZIP file to extract...", "zip"))
return false;
if (!fnDest.FileSelect(FILESELECTTYPE_ANYTHING, FILESELECT_DIRECTORY, "Choose a directory to extract to..."))
return false;
if (!zf)
return false;
zf->ExtractToDirectory(fnZip, fnDest);

Current File

Internally the ZipFile class has a pointer to the "current" file inside of the archive. The following functions provide means to change the current file pointer to another file or directory.

// This example iterates the files in ZIP archive and finds the first C4D scene (if any).
Bool sceneFound = false;
UInt32 fileSizeUncompressed = 0;
if (!zf->GoToFirstFile())
return PrintMsgAndCloseZipFile(zf, "Error: No files in ZIP archive."); // small custom helper function
do
{
// Break loop, as soon as the first scene file is encountered.
String sName;
if (zf->GetCurrentFileInfo(zfi) && !(zfi.lFlags & ZIP_FLAG_DIRECTORY) && zf->GetCurrentFileInfo(&sName) && Filename(sName).CheckSuffix("c4d"))
{
fileSizeUncompressed = zfi.lUncompressedSize;
sceneFound = true;
break;
}
} while (zf->GoToNextFile());
if (!sceneFound || fileSizeUncompressed == 0)
return PrintMsgAndCloseZipFile(zf, "Error: No C4D scene found in archive."); // small custom helper function

The current file can be extracted from a ZIP archive:

// This example demonstrates looping through the files of a ZIP file and extract each of them separately.
Filename fnZip, fnDest;
if (!fnZip.FileSelect(FILESELECTTYPE_ANYTHING, FILESELECT_LOAD, "Choose a ZIP file to extract files from..."))
return false;
if (!fnDest.FileSelect(FILESELECTTYPE_ANYTHING, FILESELECT_DIRECTORY, "Choose a destination directory for the extracted files..."))
return false;
if (!zf)
return false;
if (!zf->Open(fnZip, true)) // Open for reading.
return false;
// Iterate files and extract one by one.
if (!zf->GoToFirstFile())
{
GePrint("Error: No files in ZIP archive.");
zf->Close();
return false;
}
do
{
// Extract only files (just to demonstrate, that directory structure from archive will stay intact nevertheless).
if (zf->GetCurrentFileInfo(zfi) && !(zfi.lFlags & ZIP_FLAG_DIRECTORY))
zf->ExtractCurrentFile(fnDest);
} while (zf->GoToNextFile());
ShowInFinder(fnDest, false);
zf->Close();

Comprehensive information can be retrieved for the current file:

Similar to "normal" files (e.g. BaseFile) the current file can be opened for reading:

// This example reads the current file in chunks from a ZIP archive.
// Open the file.
if (!zf->OpenCurrentFile())
return PrintMsgAndCloseZipFile(zf, "Error: Failed to open current file in archive."); // small custom helper function
// Allocate a buffer to read the file into.
Char* buffer = NewMemClear(Char, fileSizeUncompressed);
if (!buffer)
return PrintMsgAndCloseZipFile(zf, "Error: Failed to open allocate buffer."); // small custom helper function
// Reading in chunks of 4096 (0x1000) bytes, just for demonstration purposes.
const Int32 maxChunkSize = 0x1000;
Char* bufferCurrentPos = buffer;
Char* const bufferEnd = buffer + fileSizeUncompressed; // Points to the first byte behind the allocated buffer.
while (!zf->EndOfCurrentFile())
{
const Int32 chunkSize = ClampValue((Int32)(bufferEnd - bufferCurrentPos), 0, maxChunkSize);
if (chunkSize <= 0)
break;
const Int32 numBytesRead = zf->ReadCurrentFile(bufferCurrentPos, chunkSize);
if (numBytesRead < 0)
break;
bufferCurrentPos += numBytesRead;
}
if (!zf->EndOfCurrentFile() || (bufferCurrentPos != bufferEnd))
{
DeleteMem(buffer);
return PrintMsgAndCloseZipFile(zf, "Error: Something went wrong, while reading file from archive."); // small custom helper function
}
zf->Close();

Add to an ZIP File

// This example demonstrates how a ZIP file is created and files are added.
Filename fnZip;
if (!fnZip.FileSelect(FILESELECTTYPE_ANYTHING, FILESELECT_SAVE, "Save Zip File"))
return false;
if (!zf)
return false;
if (!zf->Open(fnZip, false, ZIP_APPEND_CREATE))
return false;
Filename fnCopy;
while (fnCopy.FileSelect(FILESELECTTYPE_ANYTHING, FILESELECT_LOAD, "Select file to add to Zip File"))
{
zf->CopyInFileInZip(fnCopy, fnCopy.GetFileString());
}
zf->Close();

Further Reading