如何正确创建ZipArchive

本文关键字:ZipArchive 创建 何正确 | 更新日期: 2023-09-27 18:11:01

我正在编写桌面WPF应用程序。. Net Framework 4.5),其中一项任务是将多个文件保存到zip存档。我用了两种方法。首先创建zip文件,然后从中读取。

    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);
                    }
                }                    
            }            
        }
    }

事情是zip存档创建和远管理器和WinRAR可以打开它,但当我使用第二种方法读取其内容时,我一直得到

End of Central Directory中期望的条目数与Central Directory中的条目数不一致。在System.IO.Compression.ZipArchive.ReadCentralDirectory ()在System.IO.Compression.ZipArchive.get_Entries ()在Microsoft.MCS.SPPal.Storage.StorageObject。GetFileContent(字符串zipPath,字符串entityName)在z:'Home Inc'Microsoft.MCS.SPPal'Microsoft.MCS.SPPal'Storage'StorageObject.cs:行32'Home Inc'Microsoft.MCS.SPPal'Microsoft.MCS.SPPal' mainwindow . example .cs:line 48

作为实验的一部分,我在far管理器中创建了新的存档,并使用GetFileContent方法打开它,它像一个魅力一样工作。所以我认为错误应该在setchive方法

任何帮助都太棒了,现在是凌晨3点,我很困。

p。S:我知道代码设计很糟糕,它被重写了几十次。

如何正确创建ZipArchive

我能够通过在SetArchive()方法超出作用域之前在ZipArchive上添加对Dispose()的显式调用来实现这一点。

zip.Dispose();

当尝试打开包含使用Deflate64(通过Windows shell或7-zip创建)压缩之前大于4 GB的文件的zip文件时,我得到

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

在Windows 2012 R2上使用System.IO.Compression.ZipFile解压时。这些文件看起来是合法的压缩文件,因为Windows Shell、7-zip和Info-zip都可以解压缩它们。在System.IO.Compression.ZipFile中,唯一没有错误解压缩的大文件是用Info-zip的Zip64创建的。

为了更好的压缩,你可以使用7zip库。以这种方式:
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);
}

并调用一个方法:AddToArchive(inFolder, splitIntoDir);

你可以在这里下载7zip的源代码。

你可以在这里为Visual Studio安装7zip的Nuget包