首页 文章

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

提问于
浏览
181

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

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

System.IO.InvalidDataException:GZip标头中的幻数不正确 . 确保您传入GZip流..

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

但是,由于我能够通过手动双击压缩文件然后单击“提取所有文件”按钮来提取文件,我认为应该有一种在代码中执行此操作的方法 .

因此,我尝试将 Process.Start() 与压缩文件的路径一起用作输入 . 这会导致我的应用程序打开一个窗口,显示压缩文件中的内容 . 这一切都很好,但应用程序将安装在没有任何一个的服务器上单击"Extract all files"-按钮 .

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

或者还有另一种方法吗?我更喜欢在代码中执行此操作,而无需下载任何第三方库或应用程序;安全部门对此并不太看中......

14 回答

  • 0

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

  • 415

    使用 .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 ...见下面的评论)

  • 0

    For .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 命名空间的引用 .

  • 1

    免费,没有外部DLL文件 . 一切都在一个CS文件中 . 一个下载只是CS文件,另一个下载是一个非常容易理解的例子 . 刚刚尝试过,我无法相信设置有多简单 . 它首先尝试,没有错误,没有任何东西 .

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

  • 1

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

    用于操作zip文件的类库和工具集 . 使用VB,C#或任何.NET语言轻松创建,提取或更新zip文件...... DotNetZip可在具有完整.NET Framework的PC上运行,也可在使用.NET Compact Framework的移动设备上运行 . 在VB,C#或任何.NET语言或任何脚本环境中创建和读取zip文件...如果你想要的是一个更好的DeflateStream或GZipStream类来替换内置于.NET BCL中的那个,DotNetZip有那也是 . DotNetZip的DeflateStream和GZipStream在基于Zlib的.NET端口的独立程序集中提供 . 这些流支持压缩级别,并提供比内置类更好的性能 . 还有一个ZlibStream来完成这个集合(RFC 1950,1951,1952)......

  • 48
    String ZipPath = @"c:\my\data.zip";
    String extractPath = @"d:\\myunzips";
    ZipFile.ExtractToDirectory(ZipPath, extractPath);
    

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

  • 49

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

    要在不使用第三方库的情况下提取文件,请使用DeflateStream . 您需要有关zip文件存档格式的更多信息,因为Microsoft仅提供压缩算法 .

    您也可以尝试使用zipfldr.dll . 它是Microsoft的压缩库(发送到菜单中的压缩文件夹) . 它似乎是一个com库,但它没有记录 . 您可以通过实验让它为您工作 .

  • 67

    来自here

    写入扩展名为.gz的文件的压缩GZipStream对象可以使用许多常用的压缩工具解压缩;但是,此类本身并不提供向.zip存档添加文件或从.zip存档中提取文件的功能 .

  • 0

    我使用它来压缩或解压缩多个文件 . 正则表达式的东西不是必需的,但我用它来更改日期戳并删除不需要的下划线 . 如果需要,我使用Compress >> 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);
                }
            }
    
    
        }
    }
    
  • 8

    您可以使用DeflateStream在.NET 3.5中完成所有操作 . .NET 3.5中缺少的是能够处理用于组织压缩文件的文件头部分 . PKWare已发布此信息,您可以在创建使用的结构后处理该文件 . 它并不是特别繁琐,而且在不使用第三方代码的情况下是工具构建的一种很好的做法 .

    它不是一个答案,但如果你愿意并且能够自己花时间,这是完全可行的 . 我写了一个类来在几个小时内执行此操作,我从中获得的是仅使用.NET 3.5压缩和解压缩文件的功能 .

  • 0

    我今天发现了关于this one(NuGet上的Unzip包),因为我遇到了DotNetZip中的一个难题,我意识到过去两年在DotNetZip上没有做太多工作 .

    Unzip包非常精简,它为我完成了工作 - 它没有DotNetZip的错误 . 此外,它是一个相当小的文件,依靠Microsoft BCL进行实际的解压缩 . 我可以轻松地进行我需要的调整(能够在解压缩时跟踪进度) . 我推荐它 .

  • 1

    来自Embed Ressources:

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

    到目前为止,我正在使用cmd进程来提取.iso文件,将其从服务器复制到临时路径并在usb棒上提取 . 最近我发现这与.iso的效果完全不同,低于10Gb . 对于像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());
    
  • 26

    你可以使用 Info-unzip 命令行cod.you只需要从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; }
        }
    

相关问题