2008-11-30 25 views
29

Estoy tratando de usar SharpZipLib para extraer archivos especificados de un archivo zip. Todos los ejemplos que he visto siempre esperan que desea descomprimir toda la cremallera, y hacer algo en la línea de:¿Utiliza SharpZipLib para descomprimir archivos específicos?

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

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

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

Lo que quiero hacer es algo como:

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

Como mis necesidades implican usar un zip como un paquete y solo tomar los archivos en la memoria según sea necesario.

¿Alguien está familiarizado con SharpZipLib? ¿Alguien sabe si puedo hacer esto sin correr todo el zip a mano?

Respuesta

41

ZipFile.GetEntry debe hacer el truco:

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

si quiero extraer varios archivos desde un archivo zip en una carpeta, ¿como hacer eso?Por ejemplo, quiero obtener los archivos con el prefijo "bueno", cómo hacerlo con mi código: "var ze = zf.GetEntry (" good * ");". Gracias por cualquier idea –

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

puede extraer uno o más archivos en función de un filtro de archivos (es decir, cadena expressoin regular)

Aquí está el documento en relación con el filtro de archivos :

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

así que para un archivo llamado myfile.dat usted podría utilizar "+ * miarchivo \ .dat $." como su fil archivo ter.

6

DotNetZip tiene un indexador de cadenas en la clase ZipFile para hacerlo realmente fácil.

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

No necesita juguetear con inputstreams y outputstreams y demás, solo para extraer un archivo. Por otro lado, si desea la transmisión, puede obtenerla:

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

También puede hacer extracciones de comodines.

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

Hay sobrecargas para especificar sobrescribir/no-sobreescribir, diferentes directorios de destino, etc. También puede extraer en base a criterios distintos del nombre de archivo. Por ejemplo, extraer todos los archivos más reciente del 15 de enero de 2009:

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

Y puede combinar criterios:

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

Usted no tiene que extraer los archivos seleccionados. Puede simplemente seleccionarlos y luego tomar decisiones sobre si extraerlos o no.

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

Tengo una opción para VB.NET, para extraer archivos específicos de los archivos Zip. Comentarios en español. Tome una ruta de archivo Zip, nombre de archivo que desea extraer, contraseña si es necesario. Extraiga a la ruta original si OriginalPath está configurado a 1, o use DestPath si OriginalPath = 0. Mantenga un ojo en la materia "ICSharpCode.SharpZipLib.Zip.Compression.Streams.InflaterInputStream" ...

Es como sigue:

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