Packing and unpacking files using Zip archives in .NET
February 3, 2015 1 Comment
We’ve looked at a couple of (de)compression techniques available in .NET in previous posts, see link below. Here we’ll look at how to compress multiple files into well-known ZIP files using .NET.
.NET4.5 has added native support for ZIP files, though you need to add the following library to reach the new functions:
Say you’d like to compress all files within a folder:
DirectoryInfo filesToBeZipped = new DirectoryInfo(@"c:\zip\start"); FileInfo zipFileName = new FileInfo(@"c:\zip\zipped.zip"); ZipFile.CreateFromDirectory(filesToBeZipped.FullName, zipFileName.FullName);
…and this how you can unzip it:
DirectoryInfo extractTo = new DirectoryInfo(@"c:\zip\unzip"); ZipFile.ExtractToDirectory(zipFileName.FullName, extractTo.FullName);
The above code examples will zip and unzip all files in the directory. However, there are times when you’d like to access the individual files in the ZIP archive or add new files to an existing zip file. For this you’ll need to add one more library reference:
The following code will create the zip file and then look at each archived file one by one. If a file is larger than a certain limit then it’s extracted to a special folder:
DirectoryInfo filesToBeZipped = new DirectoryInfo(@"c:\zip\start"); FileInfo zipFileName = new FileInfo(@"c:\zip\zipped.zip"); ZipFile.CreateFromDirectory(filesToBeZipped.FullName, zipFileName.FullName); DirectoryInfo extractTo = new DirectoryInfo(@"c:\zip\unzip_individual"); if (!extractTo.Exists) { extractTo.Create(); } using (ZipArchive zipArchive = ZipFile.OpenRead(zipFileName.FullName)) { foreach (ZipArchiveEntry zipArchiveEntry in zipArchive.Entries) { Console.WriteLine(zipArchiveEntry.FullName); if (zipArchiveEntry.Length > 100) { zipArchiveEntry.ExtractToFile(Path.Combine(extractTo.FullName, zipArchiveEntry.FullName)); } } }
Here’s how you can add a existing file to an existing ZIP archive:
FileInfo zipFileName = new FileInfo(@"c:\zip\zipped.zip"); FileInfo newFileToBeAdded = new FileInfo(@"c:\temp\result.txt"); using (FileStream zipToBeExtended = new FileStream(zipFileName.FullName, FileMode.Open)) { using (ZipArchive zipArchive = new ZipArchive(zipToBeExtended, ZipArchiveMode.Update)) { ZipArchiveEntry newEntry = zipArchive.CreateEntryFromFile(newFileToBeAdded.FullName, "result-zipped.txt"); } }
This code will add “newFileToBeAdded” to the existing zip archive and name it “result-zipped.txt”.
You can also create a new zip archive entry and add content to it on the fly:
FileInfo zipFileName = new FileInfo(@"c:\zip\zipped.zip"); using (FileStream zipToBeExtended = new FileStream(zipFileName.FullName, FileMode.Open)) { using (ZipArchive zipArchive = new ZipArchive(zipToBeExtended, ZipArchiveMode.Update)) { ZipArchiveEntry newZipEntryOnTheFly = zipArchive.CreateEntry("new-result.txt"); using (StreamWriter streamWriter = new StreamWriter(newZipEntryOnTheFly.Open())) { streamWriter.WriteLine("Hello from the brand new zip archive entry!"); } } }
Read all posts dedicated to file I/O here.
Hi Andras,
How do we read each item in zipArchive.Entries in Parallel(PLINQ) and after read, need to upload each ZipArchiveEntry stream to a blob storage?