How to create ZipArchive correctly?

14,887

Solution 1

For better compression you can use 7zip library. In this way:

public void AddToArchive(string fileToBeZipped, string zipDestination)
{
    DirectoryInfo Di = new DirectoryInfo(zipDestination);
    StringBuilder sb_archiveFile = new StringBuilder(zipDestination + Path.DirectorySeparatorChar + Di.Name + @".7z");
    string archiveFile = sb_archiveFile.ToString();


    SevenZip.SevenZipCompressor compressor = new SevenZipCompressor();

    Console.WriteLine("zip destination : " + Di.Name);
    if (!File.Exists(fileToBeZipped))
    {
        Console.WriteLine("Appending {0} to Archive ", fileToBeZipped);
        compressor.CompressionMode = SevenZip.CompressionMode.Append;
    }
    else
    {
        Console.WriteLine("Creating {0} at Destination {1}....", fileToBeZipped, archiveFile);
        Console.WriteLine("CREATING:: ");
        compressor.CompressionMode = SevenZip.CompressionMode.Create;
    }
    compressor.CompressionLevel = CompressionLevel.Normal;
    compressor.CompressionMethod = CompressionMethod.Lzma;
    compressor.CompressionMode = CompressionMode.Append;

    compressor.CompressDirectory(zipDestination, archiveFile);



    compressor.CompressStream(streamer, streamer2);
}

And call a method with: AddToArchive(inFolder, splitIntoDir);

You can download a source code of 7zip here.

You can install a Nuget package for 7zip here for Visual Studio.

Solution 2

I was able to get this to work by adding an explicit call to Dispose() on the ZipArchive before it went out of scope in the SetArchive() method.

zip.Dispose();

Solution 3

When trying to open zip files containing files that were greater than 4 GB before compression that had been compressed using Deflate64 (created via Windows shell or 7-zip) I got

Number of entries expected in End Of Central Directory does not correspond to number of entries in Central Directory

when decompressing with System.IO.Compression.ZipFile on Windows 2012 R2. These files seemed to be legitimate zips because Windows Shell, 7-zip and Info-zip could decompress them. The only large file zip archives that decompressed without error with System.IO.Compression.ZipFile were those created with Info-zip's Zip64.

Share:
14,887
Admin
Author by

Admin

Updated on June 26, 2022

Comments

  • Admin
    Admin almost 2 years

    i'm writing Desktop WPF application (.Net Framework 4.5) and one of tasks is to save multiple files to zip archive. I made 2 methods. First to create zip, second to read from it.

        public static String GetFileContent(String zipPath, String entityName)
        {
            String retVal = String.Empty;
    
            using (ZipArchive zipfile = ZipFile.OpenRead(zipPath))
            {                    
                foreach (ZipArchiveEntry entry in zipfile.Entries)
                {
                    if (entry.Name.ToLower() == entityName)
                    {
                        using (StreamReader s = new StreamReader(entry.Open()))
                        {
                            retVal = s.ReadToEnd();
                            break;
                        }
                    }
                }
            }
    
            return retVal;
        }
    
        public static void SetArchive(String path, String zipName, Dictionary<String, String> files)
        {
            using (var fileStream = new FileStream(Path.Combine(path, zipName), FileMode.OpenOrCreate))
            {
                using (ZipArchive zip = new ZipArchive(fileStream, ZipArchiveMode.Create))
                {                    
                    foreach (KeyValuePair<String, String> file in files)
                    {
                        var entry = zip.CreateEntry(file.Key, CompressionLevel.Optimal);
                        using (Stream s = entry.Open())
                        {           
                            byte[] data = Encoding.UTF8.GetBytes(file.Value);
                            s.Write(data, 0, data.Length);
                        }
                    }                    
                }            
            }
        }
    

    Thing is that zip archive created and far manager and WinRAR can open it, but when I use second method to read its content I keep getting

    Number of entries expected in End Of Central Directory does not correspond to number of entries in Central Directory. at System.IO.Compression.ZipArchive.ReadCentralDirectory() at System.IO.Compression.ZipArchive.get_Entries() at Microsoft.MCS.SPPal.Storage.StorageObject.GetFileContent(String zipPath, String entityName) in z:\Home Inc\Microsoft.MCS.SPPal\Microsoft.MCS.SPPal\Storage\StorageObject.cs:line 32 at Microsoft.MCS.SPPal.MainWindow..ctor() in z:\Home Inc\Microsoft.MCS.SPPal\Microsoft.MCS.SPPal\MainWindow.xaml.cs:line 48

    As a part of experiment i created new archive in far manager and opened it up with GetFileContent method, and it works like a charm. So i think error should be in SetArchive method.

    Any help would be awesome, it's 3 a.m. and i'm quite stuck.

    P.S: I know code design suck, it was rewritten dozens of times.