Better Know a Framework: Zip / Package Multiple Files in C#

1:28:00 pm 0 Comments

Making a single archive out of multiple files in .NET is easy once you know where to look but I spent far too long realizing there is a System.IO.Packaging namespace (not in the mscorlib, but you need to reference WindowsBase assembly).
// target file
string fileName = @"C:\temp\myZip.zip";

// point to some files, say JPEG - did I say I love LINQ?
var filesToZip = new DirectoryInfo(@"c:\temp\").GetFiles("*.jpg").Select(p => p.FullName);

using (Package exportPackage = Package.Open(fileName))
{
    foreach (var file in filesToZip)
    {
        using (FileStream fileStream = File.OpenRead(file))
        {
            Uri partUriDocument = PackUriHelper.CreatePartUri(new Uri(Path.GetFileName(file), UriKind.Relative));
            PackagePart packagePart = exportPackage.CreatePart(partUriDocument, System.Net.Mime.MediaTypeNames.Image.Jpeg);
            CopyStream(fileStream, packagePart.GetStream());
        }
    }
}

// somewhere else, the CopyStream
private static void CopyStream(Stream source, Stream target)
{
    const int bufSize = 0x1000;
    byte[] buf = new byte[bufSize];
    int bytesRead = 0;
    while ((bytesRead = source.Read(buf, 0, bufSize)) > 0)
        target.Write(buf, 0, bytesRead);
}


The trap in looking for this was that searches for this all point towards the GZipStream which is nice for a single file but not applicable for packaging multiple files. In my case I wasn't even interested in compression, just a single archive. You'll find additional documentation for the library here.


I'm half tempted to write a nifty tool in IronPython for command line packaging but in a world with 7-zip, that's simply foolish.

0 comments: