.net - programa - ¿Utiliza SharpZipLib para descomprimir archivos específicos?
winrar (4)
FastZip.ExtractZip (string zipFileName, string targetDirectory, string fileFilter)
puede extraer uno o más archivos basados en un filtro de archivos (es decir, una cadena expressoin regular)
Aquí está el documento sobre 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$"
entonces, para un archivo llamado myfile.dat, podría usar "+. * myfile / .dat $" como su filtro de archivos.
Intento usar SharpZipLib para extraer archivos especificados de un archivo zip. Todos los ejemplos que he visto siempre esperan que quiera descomprimir el zip completo, y hacer algo como:
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 así 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?
DotNetZip tiene un indexador de cadenas en la clase ZipFile para que esto sea realmente fácil.
using (ZipFile zip = ZipFile.Read(sourcePath)
{
zip["NameOfFileToUnzip.txt"].Extract();
}
No necesita juguetear con los flujos de entrada y los canales de salida, etc., solo para extraer un archivo. Por otro lado, si quieres la transmisión, puedes obtenerla:
using (ZipFile zip = ZipFile.Read(sourcePath)
{
Stream s = zip["NameOfFileToUnzip.txt"].OpenReader();
// fiddle with stream here
}
También puedes 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 sobrescribir, diferentes directorios de destino, etc. También puede extraer en base a criterios distintos al nombre del archivo. Por ejemplo, extraiga todos los archivos más nuevos que el 15 de enero de 2009:
// extract all files modified after 15 Jan 2009
zip.ExtractSelectedEntries("mtime > 2009-01-15");
Y puedes 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");
No tiene que extraer los archivos que seleccione. 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();
}
}
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 "ICSharpCode.SharpZipLib.Zip.Compression.Streams.InflaterInputStream" cosas ...
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
ZipFile.GetEntry debería 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
}
}