Skip Navigation Links
Skip Navigation LinksHome > ZipArchive > How to Use > Article
Providing Custom Data: Extra Fields
Applies To: All

Introduction

  • You can store custom data along with compressed files. The custom data is saved in extra fields. Extra fields can be present in two locations: in the local file header and in the central directory. You can store your custom data in one or both of the locations.
  • You need to choose a unique identifier for your extra data that should not collide with existing mappings. You can find more information about the format of extra field and currently known mappings in the Appnote.txt file from PKWARE. This file is also distributed with the ZipArchive Library. The ZipArchive Library uses the following identifiers:
    • 0x0001 - for Zip64 extensions
    • 0x000A - for storing full file times information
    • 0x9901 - for WinZip AES encryption
    • 0x7075 - for Unicode filenames
    • 0x6375 - for Unicode file comments
    • 0x5A4C - for storing strings code pages and Unicode filenames using custom Unicode implementation (see Unicode Support: Using Non-English Characters in Filenames, Comments and Passwords).
    • 0x5A4D - for saving offsets array from seekable compressed data
  • Extra fields collections are accessible through:
  • The CZipExtraData class represents the custom data.
  • You can create and add a CZipExtraData object to the local or central field using the CZipExtraField::CreateNew(WORD) method or its overload.
  • You can read and write custom data using the CZipExtraData::m_data member.

Writing Local Extra Field

You can specify local extra fields only when creating a new file in an archive, because the local header is written at that time. You need to:
Sample Code
// define your id
const WORD id = 0xABCD;
CZipArchive zip;
zip.Open(_T("C:\\Temp\\test.zip"), CZipArchive::zipCreate);
// prepare a template of the file to add
CZipFileHeader templ;
templ.SetFileName(_T("file.dat"));
// create a local extra field
CZipExtraData* extra = templ.m_aLocalExtraData.CreateNew(id);
// copy some data to the extra field
const char* data = "data to save";
size_t dataSize = strlen(data);
extra->m_data.Allocate((DWORD)dataSize);
memcpy(extra->m_data, data, dataSize);
// for simplicity, create an empty file
zip.OpenNewFile(templ);
zip.CloseNewFile();
zip.Close();

Writing Central Extra Field

  • You can modify central extra fields at any time, but you need to remember that they are saved when the central directory is saved to an archive.
  • The central directory is removed from an archive with any other modification and saved back when you call CZipArchive::Close() or CZipArchive::Finalize(). To read more about saving the central directory, see Compressing Data.
  • If you are not sure if the central directory is saved, request the information with the CZipArchive::GetCentralDirInfo() method.
  • If the central directory is saved and you don't want to do any other modifications, you can remove the central directory with the CZipArchive::RemoveCentralDirectoryFromArchive() method. This won't work for existing segmented archives, because the ZipArchive Library does not support their modification.
Sample Code
// define your id
const WORD id = 0xABCD;
CZipArchive zip;
// open an existing file
zip.Open(_T("C:\\Temp\\test.zip"));
// create a new central extra field
CZipExtraData* extra = zip[0]->m_aCentralExtraData.CreateNew(id);
// copy some data to the extra field
const char* data = "data to save";
size_t dataSize = strlen(data);
extra->m_data.Allocate((DWORD)dataSize);
memcpy(extra->m_data, data, dataSize);
// resave the central directory
zip.RemoveCentralDirectoryFromArchive();
zip.Close();

Reading Extra Fields

Sample Code
// define your id
const WORD id = 0xABCD;
CZipArchive zip;
// open an existing file
zip.Open(_T("C:\\Temp\\test.zip"));
const int index = 0;
// update the local header
// it would already be valid, if the file was
// extracted before
zip.OpenFile(index);
zip.CloseFile();
const CZipFileHeader* info = zip[index];
// read local header
CZipExtraData* extra = info->m_aLocalExtraData.Lookup(id);
if (extra != NULL)
{
// ... process data
}
extra = info->m_aCentralExtraData.Lookup(id);
if (extra != NULL)
{
// ... process data
}
zip.Close();
Article ID: 0610242300
Back To Top Up