Skip to content
DavidPierson edited this page Jan 18, 2011 · 3 revisions

How to use SharpZipLib to update Zip files

This page shows how to update an existing zip file. Contents may be added, overwritten or deleted.

Basic updating of a zip file

First example shows how to add or overwrite entries in a zip file on disk. This concentrates on the essentials.

Please note for AES: this will not work in the 0.86.0 release, if the existing zip has entries encrypted with AES. In that case you will need to repack into a new zip - see the Unpack and Repack sample at Zip Code Samples - creating and extracting

using ICSharpCode.SharpZipLib.Zip;

public void UpdateExistingZip() {
	ZipFile zipFile = new ZipFile(@"c:\temp\existing.zip");

	// Must call BeginUpdate to start, and CommitUpdate at the end.
	zipFile.BeginUpdate();

	zipFile.Password = "whatever"; // Only if a password is wanted on the new entry

	// The "Add()" method will add or overwrite as necessary.
	// When the optional entryName parameter is omitted, the entry will be named
	// with the full folder path and without the drive e.g. "temp/folder/test1.txt".
	//
	zipFile.Add(@"c:\temp\folder\test1.txt");

	// Specify the entryName parameter to modify the name as it appears in the zip.
	//
	zipFile.Add(@"c:\temp\folder\test2.txt", "test2.txt");

	// Continue calling .Add until finished.

	// Both CommitUpdate and Close must be called.
	zipFile.CommitUpdate();
	zipFile.Close();
}

Updating a zip file in memory

This example uses streams for both the zip and the entry to be added/updated.

  1. When the zip is a memorystream, this is no different to updating a zip on disk, except you need to set IsStreamOwner false to avoid the memorystream being automatically closed.

  2. When the entry is in a memorystream, you must use an implementation of IStaticDataSource to provide the stream to the Zipfile.Add method. As the example shows, this is straightforward.

    using System; using System.IO; using ICSharpCode.SharpZipLib.Zip;

    ///

    /// Updates a zip file (in a disk or memorystream) adding the entry contained in the second stream. /// /// Zip file, could be a disk or memory stream. Must be seekable. /// Stream containing a file to be added. /// Name to appear in the zip entry. /// public void UpdateZipInMemory(Stream zipStream, Stream entryStream, String entryName) {
     // The zipStream is expected to contain the complete zipfile to be updated
     ZipFile zipFile = new ZipFile(zipStream);
    
     zipFile.BeginUpdate();
    
     // To use the entryStream as a file to be added to the zip,
     // we need to put it into an implementation of IStaticDataSource.
     CustomStaticDataSource sds = new CustomStaticDataSource();
     sds.SetStream(entryStream);
    
     // If an entry of the same name already exists, it will be overwritten; otherwise added.
     zipFile.Add(sds, entryName);
    
     // Both CommitUpdate and Close must be called.
     zipFile.CommitUpdate();
     // Set this so that Close does not close the memorystream
     zipFile.IsStreamOwner = false;
     zipFile.Close();
    
     // Reposition to the start for the convenience of the caller.
     zipStream.Position = 0;
    

    }

    public class CustomStaticDataSource : IStaticDataSource { private Stream _stream; // Implement method from IStaticDataSource public Stream GetSource() { return _stream; }

     // Call this to provide the memorystream
     public void SetStream(Stream inputStream) {
     	_stream = inputStream;
     	_stream.Position = 0;
     }
    

    }

    // This test harness CallingExample method illustrates the use of the UpdateZipInMemory method above. // In this example, we copy a zip file from disk into a memorystream, update it, and write the memorystream back to // a (different) disk file. Note that the UpdateZipInMemory method parameters are Stream - any stream will do, // it does not have to be a memorystream. The zipStream must be seekable, but the entryStream need not. // public void CallingExample() {

     // Read a disk file into memory
     MemoryStream msZip = new MemoryStream();
     FileStream fs = File.OpenRead(@"c:\temp\existing.zip");
    
     // This utility method copies from stream to stream.
     // Using StreamUtils.Copy is more efficient than copying whole file into am intermediate byte array.
     byte[] buffer = new byte[4096];
     ICSharpCode.SharpZipLib.Core.StreamUtils.Copy(fs, msZip, buffer);
     fs.Close();
    
     // Create an entry to be added.
     FileStream fsEntry = File.OpenRead(@"c:\temp\test1.txt");
     MemoryStream msEntry = new MemoryStream();
     ICSharpCode.SharpZipLib.Core.StreamUtils.Copy(fsEntry, msEntry, buffer);
     fsEntry.Close();
    
     // Do the update
     UpdateZipInMemory(msZip, msEntry, "test1updated.txt");
    
     // At this point, msZip contains the updated zip. We will write it to a new file.
     fs = File.Create(@"c:\temp\updated.zip");
     ICSharpCode.SharpZipLib.Core.StreamUtils.Copy(msZip, fs, new byte[4096]);
     fs.Close();
    

    }

Back to Code Reference main page

Clone this wiki locally