2012-05-16 12 views
5

Estoy intentando comprimir una gran cantidad de datos, a veces en la región de 100 GB, cuando ejecuto la rutina que he escrito, parece que el archivo sale exactamente del mismo tamaño que el tamaño anterior. ¿Alguien más ha tenido este problema con GZipStream?GZipStream en datos grandes

Mi código es el siguiente:

 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(); 

El StreamSize es un valor UInt64 8 bytes que contiene el tamaño del archivo. Escribo estos 8 bytes sin formato al inicio del archivo, así sé el tamaño original del archivo. Writeblock tiene el valor de 32kb (32768 bytes). fromStream es la transmisión de datos, en este caso, FileStream. ¿Los 8 bytes frente a los datos comprimidos van a causar un problema?

+0

¿Trabaja su código en archivos más pequeños? –

+1

¿Puedes confirmar que tu código comprime correctamente conjuntos de datos más pequeños? Un archivo de texto, por ejemplo, normalmente se comprime bien ... – Nik

Respuesta

4

Ejecuté una prueba usando el siguiente código para compresión y se ejecutó sin problemas en un archivo de 7GB y 12GB (ambos conocidos de antemano para comprimir "bien"). ¿Esta versión funciona para ti?

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); 
    } 
} 

¿Ha revisado el documentation?

El GZipStream clase no se puede descomprimir los datos que se traduce en más de 8 GB de datos sin comprimir.

es probable que tenga que encontrar una biblioteca diferente que apoyará sus necesidades o intentar romper sus datos arriba en <=8GB trozos que con seguridad se puede "cosidas" de nuevo juntos.

+2

Hola, Austin, gracias por la respuesta. Mi programa no se descomprime, así que no creo que esto importe? a menos que también sea un límite de 8gb para la compresión. – Skintkingle

+0

Hmm ... ¿y si necesitas más que eso? ¿Hay otras opciones disponibles? Parece extraño que una corriente tenga ese tipo de limitación. –

+0

Hablando de descompresión, el OP está hablando de compresión. –

-1

El código de Austin Salonen no funciona para mí (buggy, error de 4 GB).

Esta es la forma correcta:

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

Por favor explique el voto a favor? –