使用System.IO.Compression命名空间类GZIPStream和DeflateStream我成功地可以压缩和解压缩单个文件。但是,如果我将目录名作为压缩目标传递,则会出现安全性异常。我是否必须(递归地)枚举所有文件和子目录才能压缩目录?
(可能来自codeplex的dotnetzip会更好地处理这个问题,但这不是我现在所追求的)。
答案 0 :(得分:4)
当您使用GZipStream
等时,您正在压缩流;不是文件。 GZip
没有文件头信息,因此没有合理的方法来打包多个文件。为此你需要像.zip这样的东西; #ziplib将完成这项工作,但你仍然需要(IIRC)手动为每个文件提供它。
答案 1 :(得分:4)
System.IO.Compression
类无法管理多文件存档。您需要自己做一些工作来创建跟踪存档中内容的文件格式。本文可能会帮助您入门:
How to compress folders and multiple files with GZipStream and C# (System.IO.Compression.GZipStream)
但是,如果您使用的格式可以与只有WinZip或WinRAR的用户交换文件,那么您最好不要查看SharpZipLib之类的内容。
答案 2 :(得分:3)
System.IO.Compression中的类只处理流,是的。你必须自己做文件处理。我想,您可以使用SharpZipLib或类似文件来tar文件,然后压缩生成的tar文件。简单如(未经测试):
using (Stream out = new FileStream("out.tar", FileMode.CreateNew))
{
TarArchive archive = TarArchive.CreateOutputTarArchive(outStream
, TarBuffer.DefaultBlockFactor);
foreach (string name in fileNames)
{
TarEntry entry = TarEntry.CreateEntryFromFile(name);
archive.WriteEntry(entry, true);
}
}
答案 3 :(得分:1)
之前人们已经提到过这一点,内置的.Net类是一个很好的压缩流而不是目录结构。
他们还提到sharpziplib等是很好的库,我同意。他们提供有用的Zip和Tar实现。
但是......如果你的双手被捆绑并且你不能使用这些libs,请记住tar format非常简单。实现:
Stream ToTar(string path
)是一个相当简单和直接的任务(与实现压缩算法不同)
答案 4 :(得分:1)
使用Powershell和System.IO.Packaging.ZipPackage将内容压缩到。\ out.zip后面的示例here
$zipArchive = $pwd.path + "\out.zip"
[System.Reflection.Assembly]::Load("WindowsBase,Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")
$ZipPackage=[System.IO.Packaging.ZipPackage]::Open($zipArchive, [System.IO.FileMode]"OpenOrCreate", [System.IO.FileAccess]"ReadWrite")
$in = gci .\in | select -expand fullName
[array]$files = $in -replace "C:","" -replace "\\","/"
ForEach ($file In $files) {
$partName=New-Object System.Uri($file, [System.UriKind]"Relative")
$part=$ZipPackage.CreatePart($partName, "application/zip", [System.IO.Packaging.CompressionOption]"Maximum")
$bytes=[System.IO.File]::ReadAllBytes($file)
$stream=$part.GetStream()
$stream.Write($bytes, 0, $bytes.Length)
$stream.Close()
}
$ZipPackage.Close()
答案 5 :(得分:0)
您可以在纯.NET 3.0中压缩目录。
首先,您需要对WindowsBase.dll的引用。
此代码将打开或创建一个zip文件,在其中创建一个目录,然后将该文件放在该目录中。如果要压缩可能包含子目录的文件夹,则可以遍历目录中的文件并为每个文件调用此方法。然后,您可以先深度搜索子目录中的文件,为每个子目录调用方法,然后传递路径以在zip文件中创建该层次结构。
public void AddFileToZip(string zipFilename, string fileToAdd, string destDir)
{
using (Package zip = System.IO.Packaging.Package.Open(zipFilename, FileMode.OpenOrCreate))
{
string destFilename = "." + destDir + "\\" + Path.GetFileName(fileToAdd);
Uri uri = PackUriHelper.CreatePartUri(new Uri(destFilename, UriKind.Relative));
if (zip.PartExists(uri))
{
zip.DeletePart(uri);
}
PackagePart part = zip.CreatePart(uri, "", CompressionOption.Normal);
using (FileStream fileStream = new FileStream(fileToAdd, FileMode.Open, FileAccess.Read))
{
using (Stream dest = part.GetStream())
{
CopyStream(fileStream, dest);
}
}
}
}
destDir可以是一个空字符串,它将直接将文件放在zip中。
https://weblogs.asp.net/albertpascual/creating-a-folder-inside-the-zip-file-with-system-io-packaging