2012-05-16 19 views
5

Sto tentando di comprimere una grande quantità di dati, a volte nell'area di 100 GB, quando eseguo la routine che ho scritto sembra che il file esca esattamente della stessa dimensione della dimensione precedente. Qualcun altro ha avuto questo problema con GZipStream?GZipStream su dati di grandi dimensioni

Il mio codice è il seguente:

 byte[] buffer = BitConverter.GetBytes(StreamSize); 
     FileStream LocalUnCompressedFS = File.OpenWrite(ldiFileName); 
     LocalUnCompressedFS.Write(buffer, 0, buffer.Length); 
     GZipStream LocalFS = new GZipStream(LocalUnCompressedFS, CompressionMode.Compress); 
     buffer = new byte[WriteBlock]; 
     UInt64 WrittenBytes = 0; 
     while (WrittenBytes + WriteBlock < StreamSize) 
     { 
      fromStream.Read(buffer, 0, (int)WriteBlock); 
      LocalFS.Write(buffer, 0, (int)WriteBlock); 
      WrittenBytes += WriteBlock; 
      OnLDIFileProgress(WrittenBytes, StreamSize); 
      if (Cancel) 
       break; 
     } 
     if (!Cancel) 
     { 
      double bytesleft = StreamSize - WrittenBytes; 
      fromStream.Read(buffer, 0, (int)bytesleft); 
      LocalFS.Write(buffer, 0, (int)bytesleft); 
      WrittenBytes += (uint)bytesleft; 
      OnLDIFileProgress(WrittenBytes, StreamSize); 
     } 
     LocalFS.Close(); 
     fromStream.Close(); 

Lo streamsize è un valore UInt64 di 8 byte che contiene la dimensione del file. scrivo questi 8 byte crudi all'inizio del file in modo da conoscere la dimensione del file originale. Writeblock ha il valore di 32kb (32768 byte). fromStream è lo stream per prelevare dati da, in questo caso, da FileStream. Gli 8 byte di fronte ai dati compressi causeranno un problema?

+0

funziona il vostro codice su file più piccoli? –

+1

Puoi confermare che il tuo codice comprime correttamente dataset più piccoli - un file di testo, ad esempio, sai che normalmente si comprime bene ... – Nik

risposta

4

Ho eseguito un test utilizzando il seguente codice per la compressione ed è stato eseguito senza problemi su un file da 7 GB e 12 GB (entrambi noti in precedenza per comprimere "bene"). Questa versione funziona per te?

const string toCompress = @"input.file"; 
var buffer = new byte[1024*1024*64]; 

using(var compressing = new GZipStream(File.OpenWrite(@"output.gz"), CompressionMode.Compress)) 
using(var file = File.OpenRead(toCompress)) 
{ 
    var bytesRead = 0; 
    while(bytesRead < buffer.Length) 
    { 
     bytesRead = file.Read(buffer, 0, buffer.Length); 
     compressing.Write(buffer, 0, buffer.Length); 
    } 
} 

Avete verificato la documentation?

Il GZipStream classe non può decomprimere i dati che si traduce in oltre 8 GB di dati non compressi.

Probabilmente bisogno di trovare una libreria diversa che sosterrà le vostre esigenze o tentare di suddividere i dati su in <=8GB pezzi che possono tranquillamente essere "cucite" di nuovo insieme.

+2

Ciao Austin, grazie per la risposta. Il mio programma non si decomprimerà quindi non penso che questo sia importante? a meno che non sia anche un limite di 8 gb alla compressione. – Skintkingle

+0

Hmm ... e se ne avessi bisogno di più? Ci sono altre opzioni disponibili? Sembra strano che un flusso abbia quel tipo di limitazione. –

+0

Questo sta parlando di decompressione, l'OP sta parlando di compressione. –

-1

Il codice di Austin Salonen non funziona per me (errore di buggy, 4 GB).

Ecco il modo corretto:

using System; 
using System.Collections.Generic; 
using System.Text; 

namespace CompressFile 
{ 
    class Program 
    { 


     static void Main(string[] args) 
     { 
      string FileToCompress = @"D:\Program Files (x86)\msvc\wkhtmltopdf64\bin\wkhtmltox64.dll"; 
      FileToCompress = @"D:\Program Files (x86)\msvc\wkhtmltopdf32\bin\wkhtmltox32.dll"; 
      string CompressedFile = System.IO.Path.Combine(
       System.IO.Path.GetDirectoryName(FileToCompress) 
       ,System.IO.Path.GetFileName(FileToCompress) + ".gz" 
      ); 


      CompressFile(FileToCompress, CompressedFile); 
      // CompressFile_AllInOne(FileToCompress, CompressedFile); 

      Console.WriteLine(Environment.NewLine); 
      Console.WriteLine(" --- Press any key to continue --- "); 
      Console.ReadKey(); 
     } // End Sub Main 


     public static void CompressFile(string FileToCompress, string CompressedFile) 
     { 
      //byte[] buffer = new byte[1024 * 1024 * 64]; 
      byte[] buffer = new byte[1024 * 1024]; // 1MB 

      using (System.IO.FileStream sourceFile = System.IO.File.OpenRead(FileToCompress)) 
      { 

       using (System.IO.FileStream destinationFile = System.IO.File.Create(CompressedFile)) 
       { 

        using (System.IO.Compression.GZipStream output = new System.IO.Compression.GZipStream(destinationFile, 
         System.IO.Compression.CompressionMode.Compress)) 
        { 
         int bytesRead = 0; 
         while (bytesRead < sourceFile.Length) 
         { 
          int ReadLength = sourceFile.Read(buffer, 0, buffer.Length); 
          output.Write(buffer, 0, ReadLength); 
          output.Flush(); 
          bytesRead += ReadLength; 
         } // Whend 

         destinationFile.Flush(); 
        } // End Using System.IO.Compression.GZipStream output 

        destinationFile.Close(); 
       } // End Using System.IO.FileStream destinationFile 

       // Close the files. 
       sourceFile.Close(); 
      } // End Using System.IO.FileStream sourceFile 

     } // End Sub CompressFile 


     public static void CompressFile_AllInOne(string FileToCompress, string CompressedFile) 
     { 
      using (System.IO.FileStream sourceFile = System.IO.File.OpenRead(FileToCompress)) 
      { 
       using (System.IO.FileStream destinationFile = System.IO.File.Create(CompressedFile)) 
       { 

        byte[] buffer = new byte[sourceFile.Length]; 
        sourceFile.Read(buffer, 0, buffer.Length); 

        using (System.IO.Compression.GZipStream output = new System.IO.Compression.GZipStream(destinationFile, 
         System.IO.Compression.CompressionMode.Compress)) 
        { 
         output.Write(buffer, 0, buffer.Length); 
         output.Flush(); 
         destinationFile.Flush(); 
        } // End Using System.IO.Compression.GZipStream output 

        // Close the files.   
        destinationFile.Close(); 
       } // End Using System.IO.FileStream destinationFile 

       sourceFile.Close(); 
      } // End Using System.IO.FileStream sourceFile 

     } // End Sub CompressFile 


    } // End Class Program 


} // End Namespace CompressFile 
+0

Si prega di spiegare il downvote?! –

Problemi correlati