2008-11-30 122 views
29

我想使用SharpZipLib從zip壓縮文件中提取指定的文件。所有我一直看到的例子想到要解壓縮整個ZIP,做線沿線的東西:使用SharpZipLib解壓縮特定文件?

 FileStream fileStreamIn = new FileStream (sourcePath, FileMode.Open, FileAccess.Read); 

     ZipInputStream zipInStream = new ZipInputStream(fileStreamIn); 
     ZipEntry entry; 

     while (entry = zipInStream.GetNextEntry() != null) 
     { 
      // Unzip file 
     } 

我想要做的是一樣的東西:

ZipEntry entry = zipInStream.SeekToFile("FileName"); 

由於我的需求涉及使用壓縮包作爲包,並且只根據需要將文件抓取到內存中。

是否有人熟悉SharpZipLib?有沒有人知道如果我可以做到這一點,而無需手動通過整個拉鍊?

回答

41

ZipFile.GetEntry應該做的伎倆:

using (var fs = new FileStream(sourcePath, FileMode.Open, FileAccess.Read)) 
using (var zf = new ZipFile(fs)) { 
    var ze = zf.GetEntry(fileName); 
    if (ze == null) { 
     throw new ArgumentException(fileName, "not found in Zip"); 
    } 

    using (var s = zf.GetInputStream(ze)) { 
     // do something with ZipInputStream 
    } 
} 
+0

如果我想從一個zip文件的幾個文件解壓縮到一個文件夾,怎麼做?例如,我想獲得前綴爲「好」的文件,如何用我的代碼做到這一點:「var ze = zf.GetEntry(」good *「);」。感謝您的任何想法。 – 2010-11-03 16:43:36

13
FastZip.ExtractZip (string zipFileName, string targetDirectory, string fileFilter) 

可以提取基於文件過濾器的一個或多個文件(即定期expressoin字符串)

下面是關於文件過濾器的文檔:

// A filter is a sequence of independant <see cref="Regex">regular expressions</see> separated by semi-colons ';' 
// Each expression can be prefixed by a plus '+' sign or a minus '-' sign to denote the expression 
// is intended to include or exclude names. If neither a plus or minus sign is found include is the default 
// A given name is tested for inclusion before checking exclusions. Only names matching an include spec 
// and not matching an exclude spec are deemed to match the filter. 
// An empty filter matches any name. 
// </summary> 
// <example>The following expression includes all name ending in '.dat' with the exception of 'dummy.dat' 
// "+\.dat$;-^dummy\.dat$" 

所以名爲MYFILE.DAT你可以使用文件 「+ * MYFILE \ $ .DAT」 作爲文件FIL之三。

6

DotNetZip在ZipFile類上有一個字符串索引器,使它非常容易。

using (ZipFile zip = ZipFile.Read(sourcePath) 
{ 
    zip["NameOfFileToUnzip.txt"].Extract(); 
} 

您不需要擺弄inputstreams和outputstreams等等,只是爲了提取文件。另一方面,如果你想要流,你可以得到它:

using (ZipFile zip = ZipFile.Read(sourcePath) 
{ 
    Stream s = zip["NameOfFileToUnzip.txt"].OpenReader(); 
    // fiddle with stream here 
} 

你也可以做通配符提取。

using (ZipFile zip = ZipFile.Read(sourcePath) 
{ 
    // extract all XML files in the archive 
    zip.ExtractSelectedEntries("*.xml"); 
} 

有重載指定覆蓋/不覆蓋,不同的目標目錄等,還可以提取基於不是文件名的其他標準。例如,提取所有文件更新於2009年1月15日:

 // extract all files modified after 15 Jan 2009 
    zip.ExtractSelectedEntries("mtime > 2009-01-15"); 

而且你可以結合標準:

 // extract all files that are modified after 15 Jan 2009) AND larger than 1mb 
    zip.ExtractSelectedEntries("mtime > 2009-01-15 and size > 1mb"); 

    // extract all XML files that are modified after 15 Jan 2009) AND larger than 1mb 
    zip.ExtractSelectedEntries("name = *.xml and mtime > 2009-01-15 and size > 1mb"); 

您不必提取您選擇的文件。您可以選擇它們,然後決定是否提取。

using (ZipFile zip1 = ZipFile.Read(ZipFileName)) 
    { 
     var PhotoShopFiles = zip1.SelectEntries("*.psd"); 
     // the selection is just an ICollection<ZipEntry> 
     foreach (ZipEntry e in PhotoShopFiles) 
     { 
      // examine metadata here, make decision on extraction 
      e.Extract(); 
     } 
    } 
2

我得到一個VB.NET選項,從Zip壓縮文件中提取特定的文件。西班牙語評論。採取一個Zip文件路徑,你想提取的文件名,密碼,如果需要的話。如果OriginalPath設置爲1,則提取到原始路徑;如果OriginalPath = 0,則使用DestPath。請留意在「ICSharpCode.SharpZipLib.Zip.Compression.Streams.InflaterInputStream」的東西...

它如下:

''' <summary> 
''' Extrae un archivo específico comprimido dentro de un archivo zip 
''' </summary> 
''' <param name="SourceZipPath"></param> 
''' <param name="FileName">Nombre del archivo buscado. Debe incluir ruta, si se comprimió usando guardar con FullPath</param> 
''' <param name="DestPath">Ruta de destino del archivo. Ver parámetro OriginalPath.</param> 
''' <param name="password">Si el archivador no tiene contraseña, puede quedar en blanco</param> 
''' <param name="OriginalPath">OriginalPath=1, extraer en la RUTA ORIGINAL. OriginalPath=0, extraer en DestPath</param> 
''' <returns></returns> 
''' <remarks></remarks> 
Public Function ExtractSpecificZipFile(ByVal SourceZipPath As String, ByVal FileName As String, _ 
ByVal DestPath As String, ByVal password As String, ByVal OriginalPath As Integer) As Boolean 
    Try 
     Dim fileStreamIn As FileStream = New FileStream(SourceZipPath, FileMode.Open, FileAccess.Read) 
     Dim fileStreamOut As FileStream 
     Dim zf As ZipFile = New ZipFile(fileStreamIn) 

     Dim Size As Integer 
     Dim buffer(4096) As Byte 

     zf.Password = password 

     Dim Zentry As ZipEntry = zf.GetEntry(FileName) 

     If (Zentry Is Nothing) Then 
      Debug.Print("not found in Zip") 
      Return False 
      Exit Function 
     End If 

     Dim fstr As ICSharpCode.SharpZipLib.Zip.Compression.Streams.InflaterInputStream 
     fstr = zf.GetInputStream(Zentry) 

     If OriginalPath = 1 Then 
      Dim strFullPath As String = Path.GetDirectoryName(Zentry.Name) 
      Directory.CreateDirectory(strFullPath) 
      fileStreamOut = New FileStream(strFullPath & "\" & Path.GetFileName(Zentry.Name), FileMode.Create, FileAccess.Write) 
     Else 
      fileStreamOut = New FileStream(DestPath + "\" + Path.GetFileName(Zentry.Name), FileMode.Create, FileAccess.Write) 
     End If 


     Do 
      Size = fstr.Read(buffer, 0, buffer.Length) 
      fileStreamOut.Write(buffer, 0, Size) 
     Loop While (Size > 0) 

     fstr.Close() 
     fileStreamOut.Close() 
     fileStreamIn.Close() 
     Return True 
    Catch ex As Exception 
     Return False 
    End Try 

End Function