Modifying an archive

Archive formats such as zip

To modify an existing archive, write a new copy of the archive to a new file, making any necessary changes along the way and transferring any unchanged entries using CopyEntry(). For archive types which compress entry data, CopyEntry() is likely to be much more efficient than transferring the data using Read() and Write() since it will copy them without decompressing and recompressing them.

In general modifications are not possible without rewriting the archive, though it may be possible in some limited cases. Even then, rewriting the archive is usually a better choice since a failure can be handled without losing the whole archive. wxTempFileOutputStream can be helpful to do this.

For example to delete all entries matching the pattern "*.txt":

    wxFFileInputStreamPtr in(new wxFFileInputStream(_T("test.zip")));
    wxTempFileOutputStream out(_T("test.zip"));

    wxZipInputStream inzip(*in);
    wxZipOutputStream outzip(out);

    // 'smart pointer' type created with wxDEFINE_SCOPED_PTR_TYPE
    wxZipEntryPtr entry;

    // transfer any meta-data for the archive as a whole (the zip comment
    // in the case of zip)
    outzip.CopyArchiveMetaData(inzip);

    // call CopyEntry for each entry except those matching the pattern
    while (entry.reset(inzip.GetNextEntry()), entry.get() != NULL)
        if (!entry->GetName().Matches(_T("*.txt")))
            if (!outzip.CopyEntry(entry.release(), inzip))
                break;

    // close the input stream by releasing the pointer to it, do this
    // before closing the output stream so that the file can be replaced
    in.reset();

    // you can check for success as follows
    bool success = inzip.Eof() && outzip.Close() && out.Commit();

The smart pointer types wxZipEntryPtr and wxFFileInputStreamPtr can be created like this:

    #include <wx/ptr_scpd.h>
    wxDEFINE_SCOPED_PTR_TYPE(wxZipEntry);
    wxDEFINE_SCOPED_PTR_TYPE(wxFFileInputStream);

ymasuda 平成17年11月19日