2008-10-08 15 views
19

Sé que hay libraries out there for working with ZIP files. Y, alternativamente, puede use the functionality built into Windows for working ZIP files.¿Cómo se usa System.IO.Compression para leer/escribir archivos ZIP?

Pero, me pregunto si alguien ha descubierto cómo usar las herramientas integradas en el espacio de nombres System.IO.Compression dentro de .NET para leer/escribir archivos ZIP? O, ¿no es posible usar solo este espacio de nombres?

ACTUALIZADO: Parece que alguien comenta que el espacio de nombres System.IO.Packaging también puede ser útil con esto. ¿Alguien sabe exactamente cómo hacerlo?

Respuesta

15

MSDN tiene un completo examplehttp://msdn.microsoft.com/en-us/library/system.io.packaging.zippackage.aspx usando la clase ZipPackage. Requiere .NET 3.5.

+5

En realidad, el espacio de nombres 'System.IO.Packaging' contiene clases para trabajar con paquetes de estilo de Open Packaging. Puede usarlo para crear archivos ZIP (si no le importan algunos archivos adicionales que se incluirán en su ZIP), pero no se puede usar para abrir * ningún archivo * zip. Consulte [la parte inferior de la documentación de la clase ZipPackage] (http://msdn.microsoft.com/en-us/library/system.io.packaging.zippackage (v = vs.85) .aspx) para obtener más información (esta comunidad no es presente en el documento .NET 4.0 pero sigue siendo válido). – larsmoa

0

Sí, lo he usado en el pasado. Subclasifed DataSet una vez para soportar persistir a un archivo (a través del método ReadXML/WriteXML). Como una ventaja adicional, decidí permitir que, opcionalmente, se comprimiera si lo deseaba (esto, como ya deberían saber, es extremadamente efectivo con datos textuales como XML).

he utilizado la GZipStream clase (que era mi entendimiento en el momento en que la relacionada DeflateStream era simplemente GZip sin información de cabecera, o algo por el — estoy seguro de que alguien me podría corregir en esto). Funciona de manera sencilla mediante el uso de piggy-backing en la parte superior de otra secuencia y, por lo tanto, luego utiliza el GZipStream en su lugar. En mi caso, era una copia de seguridad en FileStream.

dado un MemoryStream para ser llenado con la salida de myDataSet.WriteXML(), hice algo como lo siguiente:

if (CompressData) 
{ 
    // Write to memory 
    mStream = new MemoryStream(); 
    Save(mStream); 
    mStream.Seek(0, SeekOrigin.Begin); 

    // Filter that through a GZipStream and then to file 
    fStream = new FileStream(Path.Combine(CacheFilePath, FileName + ".gz"), 
          FileMode.OpenOrCreate); 
    zipStream = new GZipStream(fStream, CompressionMode.Compress, true); 

    Pump(mStream, zipStream); 
} 
else 
{ 
    // Write straight to file 
    fStream = new FileStream(Path.Combine(CacheFilePath, FileName), 
          FileMode.OpenOrCreate); 
    Save(fStream); 
} 

Dónde Save() y Pump() son métodos simples como los siguientes:

private void Pump(Stream input, Stream output) 
{ 
    int n; 
    byte[] bytes = new byte[4096]; // 4KiB at a time 

    while ((n = input.Read(bytes, 0, bytes.Length)) != 0) 
    { 
     output.Write(bytes, 0, n); 
    } 
} 

public void Save(Stream stream) 
{ 
    AcceptChanges(); 

    WriteXml(stream, XmlWriteMode.WriteSchema); 
} 
+0

Su solución no lee ni escribe en el formato de archivo ZIP, sino simplemente en la compresión de desinflado sin procesar, o en la extensión simple de encabezado y pie de página de GZip alrededor de la compresión de desinflado. –

+0

+1 su respuesta podría no crear archivos ZIP, pero muestra cómo usar System.IO.Compression, que es ideal para comprimir archivos en SSIS donde está restringido a .NET 2.0 y es difícil usar librerías externas. – bstoney

6

Se hará desea utilizar una biblioteca de terceros, como http://www.codeplex.com/DotNetZip, en lugar de tratar de usar GZipStream o DeflateStream para leer un archivo zip.

Las clases *** Stream en .NET pueden permitirle leer o escribir flujos de bytes comprimidos. Estas clases NO leen ni escriben archivos zip. El archivo zip es datos comprimidos rodeados por "un sobre" o un encabezado. Piénselo como metadatos: incluye el nombre del archivo, la marca de tiempo, el CRC y un montón de otras cosas. Las ** clases Stream producen solo la secuencia de datos comprimidos, y no saben cómo producir o consumir los metadatos, que se describen en la especificación de formato PKZip mantenida por PKWare.

Las bibliotecas de terceros como DotNetZip manejan los metadatos en un archivo ZIP. Pueden o no pueden usar la clase System.IO.Compression.DeflateStream() para producir la secuencia comprimida de bytes. En versiones anteriores, por ejemplo, DotNetZip utilizaba el DeflateStream incorporado. A partir de v1.7, DotNetZip incluye su propio DeflateStream que es más eficiente que el enviado en .NET Framework. Como beneficio adicional, el DeflateStream incrustado en DotNetZip permite utilizar DotNetZip en .NET Compact Framework 2.0, que carece de System.IO.Compression.DeflateStream. (se ha agregado en Compact Framework 3.5)

Hay un buen foro en el sitio DotNetZip si tiene más preguntas. Ejemplo de código C#:

try 
    { 
     using (ZipFile zip = new ZipFile()) 
     { 
      zip.AddDirectory(DirectoryToZip); // recurses subdirs 
      zip.Save(Filename); 
     } 
    } 
    catch (System.Exception ex1) 
    { 
     System.Console.Error.WriteLine("exception: " + ex1); 
    } 
0
public static void zIpDatabseFile(string srcPath, string destPath) 
    {//This is for Zip a File 
     using (var source = new FileStream(srcPath, FileMode.Open, FileAccess.Read, FileShare.Read)) 
     using (var dest = new FileStream(destPath, FileMode.OpenOrCreate, FileAccess.Write)) 
     using (var zip = new GZipStream(dest, CompressionMode.Compress)) 
     { 
      source.CopyTo(zip); 
     } 
    } 
    public static void uNzIpDatabaseFile(string SrcPath, string DestPath) 
    {// This is for unzip a files. 
     using (var source = new FileStream(SrcPath, FileMode.Open, FileAccess.Read, FileShare.Read)) 
     using (var dest = new FileStream(DestPath, FileMode.OpenOrCreate, FileAccess.Write)) 
     using (var zip = new GZipStream(source, CompressionMode.Decompress)) 
     { 
      zip.CopyTo(dest); 
     } 
    } 
5

Desde .NET 4.5, Microsoft ha ofrecido la clase ZipArchive a la System.IO.Compression espacio de nombres. Sin embargo, a diferencia de otras clases en ese espacio de nombres, como GZipStream y Deflate, el ZipArchiverequiere una referencia al ensamblado System.IO.Compression.dll.

Es bastante simple de usar, y el enlace de arriba a MSDN proporciona algunos buenos ejemplos.

Además, Microsoft ha creado el Microsoft Compression NuGet package, que añade soporte para ZipArchive y clases relacionadas a Windows Phone 8 y otras bibliotecas de clases portátil

3

Un hilo mayores, lo sé, pero me gustaría señalar que. NET 4.5 agregó mejoras significativas a system.io.compression. Ahora puede manipular archivos .zip bastante bien, incluso hasta exponer archivos individuales dentro del archivo comprimido como flujos capaces de leer y escribir sin el paso de extraer y comprimir los archivos.