2011-11-21 16 views
6

Estoy trabajando en C# y estoy descargando para Internet un archivo zip con un archivo XML. y deseo cargar este archivo XML. Esto es lo que tengo hasta ahora:Descompresión de una secuencia en C#

byte[] data; 
WebClient webClient = new WebClient(); 
try { 
    data = webClient.DownloadData(downloadUrl); 
} 
catch (Exception ex) { 
    Console.WriteLine("Error in DownloadData (Ex:{0})", ex.Message); 
    throw; 
} 

if (data == null) { 
    Console.WriteLine("Bulk data is null"); 
    throw new Exception("Bulk data is null"); 
} 

//Create the stream 
MemoryStream stream = new MemoryStream(data); 
XmlDocument document = new XmlDocument(); 

//Gzip 
GZipStream gzipStream = new GZipStream(stream, CompressionMode.Decompress); 

//Load report straight from the gzip stream 
try { 
    document.Load(gzipStream); 
} 
catch (Exception ex) { 
    Console.WriteLine("Error in Load (Ex:{0})", ex.Message); 
    throw; 
} 

en document.Load Siempre estoy poniendo la siguiente excepción:
El número mágico en la cabecera GZip no es correcto. Asegúrate de pasar en una transmisión GZip.

¿Qué estoy haciendo mal?

+1

¿Estás descargando un '' GZip' o una Zip'? Los dos no son lo mismo. – Oded

+0

'zip! = Gzip' - Ver http://en.wikipedia.org/wiki/Gzip y http://en.wikipedia.org/wiki/ZIP_%28file_format%29 – Polynomial

+0

Supongo que este es mi primer error. Es un archivo zip no Gzip. –

Respuesta

5

¡Estoy usando SharpZipLib y está funcionando genial!

A continuación se muestra una función que encapsulan la biblioteca

public static void Compress(FileInfo sourceFile, string destinationFileName,string destinationTempFileName) 
     { 
      Crc32 crc = new Crc32(); 
      string zipFile = Path.Combine(sourceFile.Directory.FullName, destinationTempFileName); 
      zipFile = Path.ChangeExtension(zipFile, ZIP_EXTENSION); 

      using (FileStream fs = File.Create(zipFile)) 
      { 
       using (ZipOutputStream zOut = new ZipOutputStream(fs)) 
       { 
        zOut.SetLevel(9); 
        ZipEntry entry = new ZipEntry(ZipEntry.CleanName(destinationFileName)); 

        entry.DateTime = DateTime.Now; 
        entry.ZipFileIndex = 1; 
        entry.Size = sourceFile.Length; 

        using (FileStream sourceStream = sourceFile.OpenRead()) 
        { 
         crc.Reset(); 
         long len = sourceFile.Length; 
         byte[] buffer = new byte[bufferSize]; 
         while (len > 0) 
         { 
          int readSoFar = sourceStream.Read(buffer, 0, buffer.Length); 
          crc.Update(buffer, 0, readSoFar); 
          len -= readSoFar; 
         } 
         entry.Crc = crc.Value; 
         zOut.PutNextEntry(entry); 

         len = sourceStream.Length; 
         sourceStream.Seek(0, SeekOrigin.Begin); 
         while (len > 0) 
         { 
          int readSoFar = sourceStream.Read(buffer, 0, buffer.Length); 
          zOut.Write(buffer, 0, readSoFar); 
          len -= readSoFar; 
         } 
        } 
        zOut.Finish(); 
        zOut.Close(); 
       } 
       fs.Close(); 
      } 
     } 
1

De GZipStream Class Descripción:

objetos Comprimido GZipStream escritos en un archivo con una extensión de .gz se puede descomprimir el uso de muchas herramientas de compresión común ; Sin embargo, esta clase no inherentemente proporciona funcionalidad para añadir archivos o extraer archivos de archivos zip

Así que a menos que controles archivos del lado del servidor, sugeriría buscando biblioteca específica zip-dirigida (por ejemplo SharpZipLib)

2

Como los otros han mencionado, GZip y Zip no son lo mismo, por lo que es posible que necesite usar una biblioteca zip. Yo uso una biblioteca llamada: DotNetZip - disponibles en el siguiente sitio web:

http://dotnetzip.codeplex.com/

4

Al parecer SharpZipLib es ahora sin mantenimiento y es probable que desee evitarlo: https://stackoverflow.com/a/593030

En .NET 4.5, no hay ahora built in support for zip files , por lo que por su ejemplo sería:

var data = new WebClient().DownloadData(downloadUrl); 

//Create the stream 
var stream = new MemoryStream(data); 

var document = new XmlDocument(); 

//zip 
var zipArchive = new ZipArchive(stream); 

//Load report straight from the zip stream 
document.Load(zipArchive.Entries[0].Open()); 
3

Si tiene una matriz de bytes que contiene un archivo zip con un solo archivo, puede utilizar el ZipArchive clase para obtener una matriz de bytes descomprimida con los datos del archivo. ZipArchive se encuentra en .NET 4.5, en el conjunto System.IO.Compression.FileSystem (debe hacer referencia explícitamente).

La siguiente función, adaptada de this answer, funciona para mí:

public static byte[] UnzipSingleEntry(byte[] zipped) 
{ 
    using (var memoryStream = new MemoryStream(zipped)) 
    { 
     using (var archive = new ZipArchive(memoryStream)) 
     { 
      foreach (ZipArchiveEntry entry in archive.Entries) 
      { 
       using (var entryStream = entry.Open()) 
       { 
        using (var reader = new BinaryReader(entryStream)) 
        { 
         return reader.ReadBytes((int)entry.Length); 
        } 
       } 
      } 
     } 
    } 
    return null; // To quiet my compiler 
} 
Cuestiones relacionadas