如何正确地创建ZipArchive? [英] How to create ZipArchive correctly?

查看:1470
本文介绍了如何正确地创建ZipArchive?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写的桌面WPF应用程序(.NET框架4.5)和任务之一,是将多个文件保存为zip压缩文档。我做了2种方法。首先要创建zip,第二从中读取数据。

 公共静态字符串GetFileContent(字符串zipPath,字符串的entityName)
{
字符串retVal的=的String.Empty;

使用(ZipArchive zip文件= ZipFile.OpenRead(zipPath))
{
的foreach(在zipfile.Entries ZipArchiveEntry项)
{
如果(入门.Name.ToLower()==的entityName)
{使用
(StreamReader的S =新的StreamReader(entry.Open()))
{
retVal的= s.ReadToEnd() ;
中断;
}
}
}
}

返回retVal的;
}

公共静态无效SetArchive(字符串路径,字符串zipName,字典<字符串,字符串>文件)
{
使用(VAR FILESTREAM =新的FileStream(路径.Combine(路径,zipName),FileMode.OpenOrCreate))
{
使用(ZipArchive邮编=新的ZipArchive(FILESTREAM,ZipArchiveMode.Create))
{
的foreach(KeyValuePair<字符串,字符串>文件中的文件)
{
VAR进入= zip.CreateEntry(file.Key,CompressionLevel.Optimal);
使用(流S = entry.Open())
{
字节[]数据= Encoding.UTF8.GetBytes(file.Value);
s.Write(数据,0,data.Length);
}
}
}
}
}

事情是创建和远经理和WinRAR的可以打开它的zip压缩包,但是当我使用第二种方法来读取其内容我不断收到




预计在结束中央目录条目的数量不对应于中央目录条目数。
在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:在Microsoft.MCS.SPPal.MainWindow线32
。 .ctor()中的Z:\Home Inc\Microsoft.MCS.SPPal\Microsoft.MCS.SPPal\MainWindow.xaml.cs:48行




作为试验的一部分,我在遥远管理器创建新的存档,并与GetFileContent方法打开它,和它的作品就像一个魅力。所以,我认为错误应该在SetArchive方法。



任何帮助将是真棒,这是凌晨3点,我很坚持。



PS:我知道,代码设计吮吸,它被改写数十次


解决方案

有关更好的压缩,您可以使用7zip的库。通过这种方式:




 公共无效AddToArchive(字符串fileToBeZipped,串zipDestination)
{
DirectoryInfo的DI =新DirectoryInfo的(zipDestination);
StringBuilder的sb_archiveFile =新的StringBuilder(zipDestination + Path.DirectorySeparatorChar + Di.Name + @7z格式);
串archiveFile = sb_archiveFile.ToString();


SevenZip.SevenZipCompressor压缩机=新SevenZipCompressor();

Console.WriteLine(ZIP目标:+ Di.Name);
如果
{
Console.WriteLine(追加{0}到压缩文件,fileToBeZipped)(File.Exists(fileToBeZipped)!);
compressor.CompressionMode = SevenZip.CompressionMode.Append;
}
,否则
{
Console.WriteLine(创建{0}的目标{1} ....,fileToBeZipped,archiveFile);
Console.WriteLine(创建::);
compressor.CompressionMode = SevenZip.CompressionMode.Create;
}
compressor.CompressionLevel = CompressionLevel.Normal;
compressor.CompressionMethod = CompressionMethod.Lzma;
compressor.CompressionMode = CompressionMode.Append;

compressor.CompressDirectory(zipDestination,archiveFile);



compressor.CompressStream(流光,streamer2);
}

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



您可以下载7zip的源代码的这里



您可以安装的NuGet包7zip的的这里的Visual Studio。


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.

解决方案

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.

这篇关于如何正确地创建ZipArchive?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆