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

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

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

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

我现在意识到.zip文件和.gz文件是不一样的,而且GZipZip也不一样。

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

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

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

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

345703 次浏览

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

用于操作zip文件的类库和工具集。使用VB, c#或任何.NET语言轻松创建,提取,或更新zip文件…

DotNetZip可以在带有完整。net框架的pc上运行,也可以在使用。net紧凑框架的移动设备上运行。创建和读取压缩文件在VB, c#,或任何。net语言,或任何脚本环境…

如果你只是想要一个更好的DeflateStream或GZipStream类来取代。net BCL中内置的类,DotNetZip也有。DotNetZip的DeflateStream和GZipStream是基于Zlib的. net端口的独立程序集。这些流支持压缩级别,并提供比内置类更好的性能。还有一个ZlibStream来完成集合(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.Compression.FileSystem中。(由于nateirvin……见下面的评论)。您需要向框架程序集System.IO.Compression.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);
}
}




}
}

我发现关于这一个 (Unzip包在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.Compression.ZipFile.ExtractToDirectory(ZipName, ExtractToPath)