6

我正在编写桌面 WPF 应用程序(.Net Framework 4.5),其中一项任务是将多个文件保存到 zip 存档中。我做了2个方法。首先创建 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(String zipPath, String entityName) 在 z:\Home Inc\ Microsoft.MCS.SPPal\Microsoft.MCS.SPPal\Storage\StorageObject.cs:第 32 行,位于 z:\Home Inc\Microsoft.MCS.SPPal\Microsoft.MCS 中的 Microsoft.MCS.SPPal.MainWindow..ctor()。 SPPal\MainWindow.xaml.cs:第 48 行

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

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

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

4

3 回答 3

3

在 ZipArchive 超出 SetArchive() 方法的范围之前,我可以通过在 ZipArchive 上添加对 Dispose() 的显式调用来使其工作。

zip.Dispose();
于 2013-07-23T00:12:18.493 回答
1

当尝试打开包含使用 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

System.IO.Compression.ZipFile在 Windows 2012 R2 上解压缩时。这些文件似乎是合法的 zip,因为 Windows Shell、7-zip 和 Info-zip 可以解压缩它们。唯一能正确解压的大文件 zip 档案是System.IO.Compression.ZipFile使用 Info-zip 的 Zip64 创建的。

于 2014-06-10T16:22:50.743 回答
-3

为了更好地压缩,您可以使用 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 包。

于 2013-07-23T00:30:35.250 回答