Using SharpZipLib to unzip specific files?

后端 未结 4 988
你的背包
你的背包 2020-12-04 21:57

I\'m trying to use SharpZipLib to pull specified files from a zip archive. All of the examples I\'ve seen always expect that you want to unzip the entire zip, and do somethi

相关标签:
4条回答
  • 2020-12-04 22:07

    ZipFile.GetEntry should do the trick:

    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 讨论(0)
  • 2020-12-04 22:09

    Note - this answer suggests an alternative to SharpZipLib


    DotNetZip has a string indexer on the ZipFile class to make this really easy.

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

    You don't need to fiddle with inputstreams and outputstreams and so on, just to extract a file. On the other hand if you want the stream, you can get it:

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

    You can also do wildcard extractions.

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

    There are overloads to specify overwrite/no-overwrite, different target directories, etc. You can also extract based on criteria other than the filename. For example, extract all files newer than January 15, 2009:

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

    And you can combine criteria:

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

    You don't have to extract the files that you select. You can just select them and then make decisions on whether to extract or not.

        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();
            }
        }
    
    0 讨论(0)
  • 2020-12-04 22:11
    FastZip.ExtractZip (string zipFileName, string targetDirectory, string fileFilter)
    

    can extract one or more files based on a file filter (ie regular expressoin string)

    Here's the doc regarding the file filter:

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

    so for a file named myfile.dat you could use "+.*myfile\.dat$" as your file filter.

    0 讨论(0)
  • 2020-12-04 22:30

    I get an option to VB.NET, to extract specific files from Zip archivers. Comments in Spanish. Take a Zip file path, Filename you want extracted, password if needed. Extract to original path if OriginalPath is setted to 1, or use DestPath if OriginalPath=0. Keep an eye in "ICSharpCode.SharpZipLib.Zip.Compression.Streams.InflaterInputStream" stuff...

    It's as follows:

    ''' <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
    
    0 讨论(0)
提交回复
热议问题