2009-08-30 4 views
6

Sto tentando di decomprimere un file (.gz) utilizzando la classe GZipStream inclusa nel framework .NET. Sto usando la documentazione MSDN e continuo a ricevere questa eccezione: "La scrittura sul flusso di compressione non è supportata."La scrittura nel flusso di compressione non è supportata. Utilizzo di System.IO.GZipStream

Ecco la sorgente dell'applicazione:

try 
      { 

       var infile = new FileStream(@"C:\TarDecomp\TarDecomp\TarDecomp\bin\Debug\nick_blah-2008.tar.gz", FileMode.Open, FileAccess.Read, FileShare.Read); 
       byte[] buffer = new byte[infile.Length]; 
       // Read the file to ensure it is readable. 
       int count = infile.Read(buffer, 0, buffer.Length); 
       if (count != buffer.Length) 
       { 
        infile.Close(); 
        Console.WriteLine("Test Failed: Unable to read data from file"); 
        return; 
       } 
       infile.Close(); 
       MemoryStream ms = new MemoryStream(); 
       // Use the newly created memory stream for the compressed data. 
       GZipStream compressedzipStream = new GZipStream(ms, CompressionMode.Decompress, true); 
       Console.WriteLine("Decompression"); 
       compressedzipStream.Write(buffer, 0, buffer.Length); 
       // Close the stream. 
       compressedzipStream.Close(); 
       Console.WriteLine("Original size: {0}, Compressed size: {1}", buffer.Length, ms.Length); 

L'eccezione viene generata al compressedZipStream.write().

Qualche idea? Cosa mi sta dicendo questa eccezione? Grazie!

risposta

14

Ti sta dicendo che dovresti chiamare Read invece di Write dato che è in decompressione! Anche il flusso di memoria dovrebbe essere costruito con i dati, o meglio si dovrebbe passare il flusso di file direttamente al costruttore GZipStream.

Esempio di come avrebbe dovuto essere fatto (non hanno provato a compilare):

Stream inFile = new FileStream(@"C:\TarDecomp\TarDecomp\TarDecomp\bin\Debug\nick_blah-2008.tar.gz", FileMode.Open, FileAccess.Read, FileShare.Read); 
Stream decodedStream = new MemoryStream(); 
byte[] buffer = new byte[4096]; 

using (Stream inGzipStream = new GZipStream(inFile, CompressionMode.Decompress)) 
{ 
    int bytesRead; 
    while ((bytesRead = inGzipStream.Read(buffer, 0, buffer.Length)) > 0) 
     decodedStream.Write(buffer, 0, bytesRead); 
} 

// Now decodedStream contains the decoded data 
+0

Sto provando questo grazie. – Nick

+0

Il tuo uomo .. Grazie! – Nick

+0

Felice di aiutare. :) –

1

Come compressione flussi di lavoro può essere sconcertante in un primo momento.

La lettura richiede compressa dati e scrittura dati non compressi non compresso. Tutto sommato, lo stream ti garantisce di "vedere" solo i dati non compressi in ogni momento.

Il modo corretto per ottenere ciò che si sta tentando di fare, è quello di leggere utilizzando il GZipStream e quindi scrivere utilizzando anche lo GZipStream.

9

Il codice di compressione non funziona come la crittografia: non è possibile decomprimere da un flusso all'altro scrivendo i dati compressi. Devi fornire un flusso che contiene già i dati compressi e lasciare leggere GZipStream da esso. Qualcosa di simile a questo:

using (Stream file = File.OpenRead(filename)) 
using (Stream gzip = new GZipStream(file, CompressionMode.Decompress)) 
using (Stream memoryStream = new MemoryStream()) 
{ 
    CopyStream(gzip, memoryStream); 
    return memoryStream.ToArray(); 
} 

CopyStream è un metodo semplice utility per leggere da un flusso e copiare tutti i dati ad un altro. Qualcosa del genere:

static void CopyStream(Stream input, Stream output) 
{ 
    byte[] buffer = new byte[8192]; 
    int bytesRead; 
    while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0) 
    { 
     output.Write(buffer, 0, bytesRead); 
    } 
}