2008-11-30 10 views
29

Próbuję użyć SharpZipLib wyciągnąć określone pliki z archiwum zip. Wszystkie przykłady widziałem zawsze oczekiwać, że chcesz rozpakować cały zamek, i zrobić coś na wzór:Korzystanie SharpZipLib rozpakować konkretne pliki?

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

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

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

Co chcę zrobić coś jak:

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

jak moje potrzeby polegają na użyciu zip jako pakiet i zgrywania plików do pamięci tylko w razie potrzeby.

Czy ktoś zna SharpZipLib? Czy ktoś wie, czy mogę to zrobić bez ręcznego przechodzenia przez cały zamek błyskawiczny?

Odpowiedz

41

ZipFile.GetEntry powinno załatwić sprawę:

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

jeśli chcę, aby wyodrębnić kilka plików z pliku zip do folderu, jak to zrobić?Na przykład chcę uzyskać pliki z prefiksem "dobry", jak to zrobić z moim kodem: "var ze = zf.GetEntry (" good * ");". Dzięki za wszelkie pomysły. –

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

można wyodrębnić jeden lub więcej plików opartych na filtrze plików (tj regularny ciąg expressoin)

Oto doc dotyczące filtra plików :

// 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$" 

więc dla pliku o nazwie myfile.dat można użyć "+ * myfile \ .dat $." jako fil plików ter.

6

DotNetZip ma podziałowe ciąg na klasie zipfile aby to naprawdę proste.

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

Nie trzeba się bawić z inputstreams i outputstreams i tak dalej, tak aby wyodrębnić plik. Z drugiej strony, jeśli chcesz strumień, możesz go uzyskać:

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

Można również wykonywać ekstrakcje wieloznaczne.

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

Istnieje przeciążenia aby określić nadpisanie/no-nadpisać różne katalogi docelowe itd Można także wyodrębnić na podstawie kryteriów innych niż nazwy pliku. Na przykład wyodrębnić wszystkie pliki nowsze niż 15 stycznia 2009:

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

I można połączyć kryteria:

 // 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"); 

Nie trzeba wyodrębnić pliki, które można wybrać. Możesz je po prostu wybrać, a następnie podjąć decyzję, czy wyodrębnić, czy nie.

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

Dostaję opcję do VB.NET, aby wyodrębnić określone pliki z archiwów Zip. Komentarze w języku hiszpańskim. Zrób ścieżkę pliku Zip, nazwę pliku, który chcesz wyodrębnić, hasło, jeśli to konieczne. Wyciąg z pierwotnym ścieżce, OriginalPath jest ustawiony jako 1, lub OriginalPath = 0 użyciu DestPath. Miej oko na „ICSharpCode.SharpZipLib.Zip.Compression.Streams.InflaterInputStream” rzeczy ...

To, co następuje:

''' <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