I am trying to create a new ZIP package from code with one entry and save the ZIP package to a file. I am trying to achive this with the System.IO.Compression.ZipArchive class. I am creating the ZIP package with the following code:
using (MemoryStream zipStream = new MemoryStream()) { using (ZipArchive zip = new ZipArchive(zipStream, ZipArchiveMode.Create)) { var entry = zip.CreateEntry("test.txt"); using (StreamWriter sw = new StreamWriter(entry.Open())) { sw.WriteLine( "Etiam eros nunc, hendrerit nec malesuada vitae, pretium at ligula."); }
Then I save the ZIP to a file either in WinRT:
var file = await Windows.Storage.ApplicationData.Current.LocalFolder.CreateFileAsync("test.zip", CreationCollisionOption.ReplaceExisting); zipStream.Position = 0; using (Stream s = await file.OpenStreamForWriteAsync()) { zipStream.CopyTo(s); }
Or in normal .NET 4.5:
using (FileStream fs = new FileStream(@"C:\Temp\test.zip", FileMode.Create)) { zipStream.Position = 0; zipStream.CopyTo(fs); }
However, I can't open the produced files neither in Windows Explorer, WinRAR, etc. (I checked that the size of the produced file matches the Length of the zipStream, so the stream itself was saved to the file correctly.)
Am I doing something wrong or is there a problem with the ZipArchive class?
Your Zip file is invalid because of errors like virus infection, or an incomplete download from the internet. Both of these factors can cause a Zip file to become corrupt or damaged, thus leading to the error message, "The Compressed (zipped) folder is invalid".
The Compressed (zipped) folder is invalid when a ZIP-file is corrupt. Causes may vary, but most of the time it's a ZIP file downloaded from the internet. The download may not have completed successfully.
The various reasons why you get an access denied error are: a: You may not have ownership of a file or folder. b: You may not have the proper permissions. c: The file or folder may be Encrypted.
I found the—in hindsight, obvious—error in my code. The ZipArchive has to be disposed to make it write its content to its underlying stream. So I had to save the stream to a file after the end of the using block of the ZipArchive.
And it was important to set the leaveOpen argument of its constructor to true, to make it not close the underlying stream. So here is the complete working solution:
using (MemoryStream zipStream = new MemoryStream()) { using (ZipArchive zip = new ZipArchive(zipStream, ZipArchiveMode.Create, true)) { var entry = zip.CreateEntry("test.txt"); using (StreamWriter sw = new StreamWriter(entry.Open())) { sw.WriteLine( "Etiam eros nunc, hendrerit nec malesuada vitae, pretium at ligula."); } } var file = await Windows.Storage.ApplicationData.Current.LocalFolder.CreateFileAsync( "test.zip", CreationCollisionOption.ReplaceExisting); zipStream.Position = 0; using (Stream s = await file.OpenStreamForWriteAsync()) { zipStream.CopyTo(s); } }
On all of your Stream Object you must rewind the streams from the beggining in order from them to be read correctly by other applications using the .Seek method.
Example:
zipStream.Seek(0, SeekOrigin.Begin);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With