我正在尝试以编程方式解压缩压缩文件。
我尝试在.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());
我用它来压缩或解压缩多个文件。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);
}
}
}
}