我正在尝试以编程方式解压缩压缩文件。
我尝试在.NET中使用System.IO.Compression.GZipStream
类,但是当我的应用程序运行时(实际上是一个单元测试),我得到了这个例外:
System.IO.InvalidDataException:GZip标头中的幻数不正确。确保你传入GZip流..
我现在意识到.zip
文件与.gz
文件不同,GZip
与Zip
不同。
但是,由于我能够通过手动双击压缩文件然后单击“提取所有文件”按钮来提取文件,我认为应该有一种在代码中执行此操作的方法。
因此,我尝试将Process.Start()
与压缩文件的路径一起用作输入。这会导致我的应用程序打开一个窗口,显示压缩文件中的内容。这一切都很好,但应用程序将安装在没有任何一个的服务器上单击“提取所有文件”按钮。
那么,如何让我的应用程序提取压缩文件中的文件?
还是有其他办法吗?我更喜欢在代码中执行此操作,而无需下载任何第三方库或应用程序;安全部门对此并不太看中......
答案 0 :(得分:447)
使用 .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 ......见下面的评论)
答案 1 :(得分:75)
适用于.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
的引用。
答案 2 :(得分:52)
我们已在许多项目中成功使用SharpZipLib。我知道它是第三方工具,但是包含了源代码,如果您选择在这里重新发明轮子,可以提供一些见解。
答案 3 :(得分:51)
免费,没有外部DLL文件。一切都在一个CS文件中。一个下载只是CS文件,另一个下载是一个非常容易理解的例子。刚试了今天,我简直不敢相信设置有多简单。它首先尝试,没有错误,没有任何错误。
答案 4 :(得分:27)
使用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)...
答案 5 :(得分:8)
String ZipPath = @"c:\my\data.zip";
String extractPath = @"d:\\myunzips";
ZipFile.ExtractToDirectory(ZipPath, extractPath);
要使用ZipFile类,必须在项目中添加对System.IO.Compression.FileSystem程序集的引用
答案 6 :(得分:2)
标准zip文件通常使用deflate算法。
要在不使用第三方库的情况下提取文件,请使用DeflateStream。您需要有关zip文件存档格式的更多信息,因为Microsoft仅提供压缩算法。
您也可以尝试使用zipfldr.dll。它是Microsoft的压缩库(发送到菜单中的压缩文件夹)。它似乎是一个com库,但它没有文档。您可以通过实验让它为您工作。
答案 7 :(得分:1)
来自here:
写入压缩的GZipStream对象 到扩展名为.gz的文件即可 使用许多常见的解压缩 压缩工具;但是,这堂课 本身并不提供 将文件添加到或的功能 从.zip档案中提取文件。
答案 8 :(得分:1)
我用它来压缩或解压缩多个文件。正则表达式的东西不是必需的,但我用它来更改日期戳并删除不需要的下划线。我在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);
}
}
}
}
答案 9 :(得分:1)
您可以使用DeflateStream在.NET 3.5中完成所有操作。 .NET 3.5中缺少的是能够处理用于组织压缩文件的文件头部分。 PKWare已发布此信息,您可以在创建使用的结构后使用该信息处理zip文件。它并不是特别繁琐,而且在不使用第三方代码的情况下是工具构建的一种很好的做法。
这不是一个单行的答案,但如果你愿意并且能够自己花时间,这是完全可行的。我在几个小时内编写了一个类,我从中获得的是只能使用.NET 3.5压缩和解压缩文件的能力。
答案 10 :(得分:1)
这会System.IO.Compression.ZipFile.ExtractToDirectory(ZipName, ExtractToPath)
答案 11 :(得分:0)
我今天发现了this one(NuGet上的Unzip包),因为我遇到了DotNetZip中的一个难题,我意识到过去两年在DotNetZip上没有做太多工作
Unzip包很精简,它为我完成了工作 - 它没有DotNetZip的错误。此外,它是一个相当小的文件,依靠Microsoft BCL进行实际的解压缩。我可以轻松地进行我需要的调整(能够在解压缩时跟踪进度)。我推荐它。
答案 12 :(得分:0)
来自Embed Ressources:
using (Stream _pluginZipResourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(programName + "." + "filename.zip"))
{
using (ZipArchive zip = new ZipArchive(_pluginZipResourceStream))
{
zip.ExtractToDirectory(Application.StartupPath);
}
}
答案 13 :(得分:0)
到目前为止,我正在使用cmd进程来提取.iso文件,将其从服务器复制到临时路径并在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());
答案 14 :(得分:0)
您可以使用 Info-unzip 命令行编码。您只需从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; }
}