2009-05-22 53 views
2

使用System.IO.Compression命名空間類GZIPStream和DeflateStream我成功地壓縮和解壓縮單個文件。但是,如果我傳遞一個目錄名作爲壓縮目標,我會得到一個安全異常。我必須(遞歸)枚舉所有文件和子目錄以便能夠壓縮目錄嗎?如何壓縮內置.net壓縮類的目錄?

(可能codeplex的dotnetzip會處理這個更好,但這不是我現在的)。

回答

4

當你使用GZipStream等,你正在壓縮一個;不是文件。 GZip沒有文件頭信息,所以沒有明智的方式打包多個文件。爲此你需要類似.zip的東西; #ziplib將完成這項工作,但你仍然(IIRC)需要手動爲每個文件提供它。

3

System.IO.Compression中的類將只處理流,是的。你必須自己做文件處理。我想,你可以使用SharpZipLib或類似的命令來壓縮文件,然後壓縮生成的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); 
    } 
} 
1

以前有人提到過,內建的.Net類很好的壓縮流而不是目錄結構。

他們還提到sharpziplib等..是很好的圖書館使用,我同意。他們提供有用的Zip和Tar實現。

但是......如果你的雙手綁在一起,你不能使用這些庫,請記住,tar format是非常簡單的。實施: Stream ToTar(string path)是一個相當簡單和直接的任務(不像內容執行壓縮算法)

1

這將壓縮\ \ out.zip使用PowerShell和System.IO.Packaging.ZipPackage下面的例子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()