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

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

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

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

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

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

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

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


当前回答

到目前为止,我一直在使用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());

其他回答

在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)...

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

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

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

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

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

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

您可以使用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; }
    }