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

我尝试在.NET中使用System.IO.Compression.GZipStream类,但当我的应用程序运行时(实际上是一个单元测试),我得到这个异常:

System.IO.InvalidDataException: GZip头中的魔法数字不正确。确保你传递的是一个GZip流。

我现在意识到。Zip文件和。gz文件不一样,GZip和Zip也不一样。

然而,由于我能够通过手动双击压缩文件,然后单击“提取所有文件”按钮来提取文件,我认为在代码中也应该有一种方法来做到这一点。

因此,我尝试使用Process.Start(),并将压缩文件的路径作为输入。这导致我的应用程序打开一个窗口,显示压缩文件中的内容。这一切都很好,但应用程序将被安装在一个服务器上,没有人可以点击“提取所有文件”按钮。

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

或者还有别的办法吗?我更喜欢用代码来做,而不下载任何第三方库或应用程序;安全部门对此不太感兴趣……


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

class library and toolset for manipulating zip files. Use VB, C# or any .NET language to easily create, extract, or update zip files... DotNetZip works on PCs with the full .NET Framework, and also runs on mobile devices that use the .NET Compact Framework. Create and read zip files in VB, C#, or any .NET language, or any scripting environment... If all you want is a better DeflateStream or GZipStream class to replace the one that is built-into the .NET BCL, DotNetZip has that, too. DotNetZip's DeflateStream and GZipStream are available in a standalone assembly, based on a .NET port of Zlib. These streams support compression levels and deliver much better performance than the built-in classes. There is also a ZlibStream to complete the set (RFC 1950, 1951, 1952)...


标准zip文件通常使用deflate算法。

要在不使用第三方库的情况下提取文件,请使用deflestream。您需要更多关于zip文件归档格式的信息,因为Microsoft只提供压缩算法。

您也可以尝试使用zipfldr.dll。它是微软的压缩库(从“发送到”菜单压缩文件夹)。它看起来是一个com库,但它是无文档的。你可以通过实验让它为你工作。


从这里开始:

已写入压缩的GZipStream对象 扩展名为。gz的文件可以 常用的解压方法有很多 压缩工具;然而,这个类 并不天生提供 向或中添加文件的功能 从.zip档案中提取文件。


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


免费,没有外部DLL文件。所有内容都在一个CS文件中。一个下载只是CS文件,另一个下载是一个非常容易理解的例子。今天刚试了一下,我不敢相信设置是多么简单。第一次尝试就成功了,没有错误,什么都没有。

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


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

上面的代码直接取自微软的文档:http://msdn.microsoft.com/en-us/library/ms404280(v=vs.110).aspx

ZipFile包含在系统集system . io . compress . filesystem中。(由于nateirvin……见下面的评论)。您需要向框架程序集system . io . compress . filesystem . DLL添加一个DLL引用


我用它来压缩或解压缩多个文件。Regex的东西不是必需的,但我用它来更改日期戳和删除不需要的下划线。如果需要,我使用压缩>> zipPath字符串中的空字符串为所有文件添加前缀。此外,我通常根据我正在做的事情注释掉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);
            }
        }


    }
}

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

Unzip包是精简的,它为我做了工作-它没有DotNetZip的bug。而且,它是一个相当小的文件,依赖于Microsoft BCL进行实际的解压。我可以很容易地做出调整,我需要(能够跟踪进度,同时解压)。我推荐它。


你可以在. net 3.5中使用DeflateStream来完成这一切。. net 3.5中缺少的是处理用于组织压缩文件的文件头部分的能力。PKWare已经发布了这些信息,您可以在创建使用的结构后使用这些信息来处理zip文件。它不是特别繁重,而且在不使用第三方代码的情况下构建工具是一种很好的实践。

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


对于。net 4.5+

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

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命名空间和System.IO.Compression. filesystem的引用。


来自嵌入资源:

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

到目前为止,我一直在使用cmd进程来提取一个。iso文件,将其复制到服务器的临时路径中,并提取到u盘上。最近,我发现这种方法对于小于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 . compress . filesystem程序集的引用


您可以使用Info-unzip命令行cod。你只需要从Info-unzip官方网站下载unzip.exe即可。

 internal static void Unzip(string sorcefile)
    {
        try
        {
            AFolderFiles.AFolderFilesDelete.DeleteFolder(TempBackupFolder); // delete old folder   
            AFolderFiles.AFolderFilesCreate.CreateIfNotExist(TempBackupFolder); // delete old folder   
           //need to Command command also to export attributes to a excel file
            System.Diagnostics.Process process = new System.Diagnostics.Process();
            System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
            startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; // window type
            startInfo.FileName = UnzipExe;
            startInfo.Arguments = sorcefile + " -d " + TempBackupFolder;
            process.StartInfo = startInfo;
            process.Start();
            //string result = process.StandardOutput.ReadToEnd();
            process.WaitForExit();
            process.Dispose();
            process.Close();
        }
        catch (Exception ex){ throw ex; }
    }        

这将完成system . io . compress . zipfile。ExtractToDirectory (ZipName ExtractToPath)