在.net中以编程方式解压缩文件

我正试图以编程方式解压缩压缩文件。

我曾尝试在.NET中使用System.IO.Compression.GZipStream类,但是当我的应用程序运行(实际上是一个unit testing),我得到这个exception:

System.IO.InvalidDataException:GZip标头中的幻数不正确。 确保你传入一个GZipstream

我现在意识到.zip文件与.gz文件不同,而且GZipZip

但是,由于我能够通过手动双击压缩文件来提取文件,然后单击“提取所有文件”button,我认为在代码中也应该有这样做的方法。

因此,我试图使用Process.Start()与压缩文件的path作为input。 这使我的应用程序打开一个窗口,显示压缩文件中的内容。 这一切都很好,但应用程序将被安装在一个没有周围的服务器上点击“提取所有文件”button。

那么,如何让我的应用程序提取压缩文件中的文件呢?

还是有另一种方法来做到这一点? 我更喜欢用代码来做,而不用下载任何第三方库或应用程序。 安全部门不太喜欢那个…

我们已经在许多项目上成功地使用了SharpZipLib 。 我知道这是一个第三方工具,但包含源代码,可以提供一些见解,如果你select在这里重新发明轮子。

使用.NET 4.5,您现在可以使用.NET框架解压缩文件:

 using System; using System.IO; namespace ConsoleApplication { class Program { static void Main(string[] args) { string startPath = @"c:\example\start"; string zipPath = @"c:\example\result.zip"; string extractPath = @"c:\example\extract"; System.IO.Compression.ZipFile.CreateFromDirectory(startPath, zipPath); System.IO.Compression.ZipFile.ExtractToDirectory(zipPath, extractPath); } } } 

上述代码直接从Microsoft的文档中获取: http : //msdn.microsoft.com/en-us/library/ms404280(v=vs.110).aspx

ZipFile包含在程序集System.IO.Compression.FileSystem 。 (谢谢nateirvin …见下面的评论)

免费的,没有外部的DLL文件。 一切都在一个CS文件中。 一个下载只是CS文件,另一个下载是一个很容易理解的例子。 只是今天试了一下,我不能相信这个设置是多么简单。 它首先尝试,没有错误,没有任何东西。

https://github.com/jaime-olivares/zipstorer

对于.Net 4.5+

并不总是希望将未压缩的文件写入磁盘。 作为一个ASP.Net开发人员,我将不得不摆弄权限来授予我的应用程序写入文件系统的权限。 通过在内存中处理stream,我可以回避所有这些,直接读取文件:

 using (ZipArchive archive = new ZipArchive(postedZipStream)) { foreach (ZipArchiveEntry entry in archive.Entries) { var stream = entry.Open(); //Do awesome stream stuff!! } } 

或者,您仍然可以通过调用ExtractToFile()将解压缩的文件写入磁盘:

 using (ZipArchive archive = ZipFile.OpenRead(pathToZip)) { foreach (ZipArchiveEntry entry in archive.Entries) { entry.ExtractToFile(Path.Combine(destination, entry.FullName)); } } 

要使用ZipArchive ,您需要添加对System.IO.Compression.FileSystem的引用

使用http://www.codeplex.com/DotNetZip上的DotNetZip库;

用于处理zip文件的类库和工具集。 使用VB,C#或任何.NET语言轻松创build,提取或更新压缩文件…

DotNetZip可以在装有完整.NET Framework的电脑上运行,也可以在使用.NET Compact Framework的移动设备上运行。 在VB,C#或任何.NET语言或任何脚本环境中创build和读取zip文件…

如果你想要的是一个更好的DeflateStream或者GZipStream类来代替内置于.NET BCL中的类,DotNetZip也是如此。 DotNetZip的DeflateStream和GZipStream在独立程序集中可用,基于Zlib的.NET端口。 这些stream支持压缩级别,并提供比内置类更好的性能。 还有一个ZlibStream来完成设置(RFC 1950,1951,1952)…

标准的zip文件通常使用deflatealgorithm。

要提取文件而不使用第三方库,请使用DeflateStream。 因为Microsoft只提供压缩algorithm,所以需要更多有关zip文件归档格式的信息。

您也可以尝试使用zipfldr.dll。 它是微软的压缩库(从发送到菜单的压缩文件夹)。 它似乎是一个COM库,但它是无证的。 你可能能够通过实验为你工作。

从这里 :

写入扩展名为.gz的文件的压缩GZipStream对象可以使用许多常用的压缩工具进行解压缩; 然而,这个类本身并不提供向.zip文件添加文件或者从.zip文件中提取文件的function。

我用它来压缩或解压缩多个文件。 正则expression式的东西不是必需的,但我用它来更改date戳记和删除不需要的下划线。 我使用压缩>> zipPathstring中的空string来为所有文件添加前缀(如果需要的话)。 另外,我通常基于我正在做的事情发表Compress()或Decompress()。

 using System; using System.IO.Compression; using System.IO; using System.Text.RegularExpressions; namespace ZipAndUnzip { class Program { static void Main(string[] args) { var directoryPath = new DirectoryInfo(@"C:\your_path\"); Compress(directoryPath); Decompress(directoryPath); } public static void Compress(DirectoryInfo directoryPath) { foreach (DirectoryInfo directory in directoryPath.GetDirectories()) { var path = directoryPath.FullName; var newArchiveName = Regex.Replace(directory.Name, "[0-9]{8}", "20130913"); newArchiveName = Regex.Replace(newArchiveName, "[_]+", "_"); string startPath = path + directory.Name; string zipPath = path + "" + newArchiveName + ".zip"; ZipFile.CreateFromDirectory(startPath, zipPath); } } public static void Decompress(DirectoryInfo directoryPath) { foreach (FileInfo file in directoryPath.GetFiles()) { var path = directoryPath.FullName; string zipPath = path + file.Name; string extractPath = Regex.Replace(path + file.Name, ".zip", ""); ZipFile.ExtractToDirectory(zipPath, extractPath); } } } } 

你可以使用DeflateStream在.NET 3.5中完成所有的工作。 在.NET 3.5中缺乏的是能够处理用于组织压缩文件的文件头部分。 PKWare已经发布了这个信息,你可以在创build使用的结构之后使用它来处理zip文件。 这并不是特别繁琐,而且在不使用第三方代码的情况下也是一个很好的实践工具。

这不是一个单一的答案,但如果你愿意并能够自己花时间,这是完全可行的。 我在几个小时内写了一个类来完成这个任务,而我从中得到的是只能使用.NET 3.5压缩和解压缩文件的能力。

今天我发现了这个 (NuGet上的解压缩包),因为我在DotNetZip中遇到了一个严重的bug,而且我意识到在过去的两年里,DotNetZip并没有做太多的工作。

Unzip包是精简的,它为我做了这个工作 – 它没有DotNetZip的缺陷。 此外,这是一个相当小的文件,依靠Microsoft BCL的实际解压缩。 我可以很容易地做出我需要的调整(能够在解压缩的同时跟踪进度)。 我推荐它。

来自Embed Ressources:

 using (Stream _pluginZipResourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(programName + "." + "filename.zip")) { using (ZipArchive zip = new ZipArchive(_pluginZipResourceStream)) { zip.ExtractToDirectory(Application.StartupPath); } } 

到目前为止,我使用cmd进程来提取.iso文件,将其复制到服务器的临时path中,并在USB棒上提取。 最近我发现,这是与小于10Gb的.iso的完美工作。 对于像29Gb这样的iso,这个方法会被卡住。

  public void ExtractArchive() { try { try { Directory.Delete(copyISOLocation.OutputPath, true); } catch (Exception e) when (e is IOException || e is UnauthorizedAccessException) { } Process cmd = new Process(); cmd.StartInfo.FileName = "cmd.exe"; cmd.StartInfo.RedirectStandardInput = true; cmd.StartInfo.RedirectStandardOutput = true; cmd.StartInfo.CreateNoWindow = true; cmd.StartInfo.UseShellExecute = false; cmd.StartInfo.WindowStyle = ProcessWindowStyle.Normal; //stackoverflow cmd.StartInfo.Arguments = "-R"; cmd.Disposed += (sender, args) => { Console.WriteLine("CMD Process disposed"); }; cmd.Exited += (sender, args) => { Console.WriteLine("CMD Process exited"); }; cmd.ErrorDataReceived += (sender, args) => { Console.WriteLine("CMD Process error data received"); Console.WriteLine(args.Data); }; cmd.OutputDataReceived += (sender, args) => { Console.WriteLine("CMD Process Output data received"); Console.WriteLine(args.Data); }; //stackoverflow cmd.Start(); cmd.StandardInput.WriteLine("C:"); //Console.WriteLine(cmd.StandardOutput.Read()); cmd.StandardInput.Flush(); cmd.StandardInput.WriteLine("cd C:\\\"Program Files (x86)\"\\7-Zip\\"); //Console.WriteLine(cmd.StandardOutput.ReadToEnd()); cmd.StandardInput.Flush(); cmd.StandardInput.WriteLine(string.Format("7z.exe x -o{0} {1}", copyISOLocation.OutputPath, copyISOLocation.TempIsoPath)); //Console.WriteLine(cmd.StandardOutput.ReadToEnd()); cmd.StandardInput.Flush(); cmd.StandardInput.Close(); cmd.WaitForExit(); Console.WriteLine(cmd.StandardOutput.ReadToEnd()); Console.WriteLine(cmd.StandardError.ReadToEnd()); 
 String ZipPath = @"c:\my\data.zip"; String extractPath = @"d:\\myunzips"; ZipFile.ExtractToDirectory(ZipPath, extractPath); 

要使用ZipFile类,必须在项目中添加对System.IO.Compression.FileSystem程序集的引用