2012-05-16 26 views
5

Tôi đang cố gắng nén một lượng lớn dữ liệu, đôi khi trong vùng 100GB, khi tôi chạy thường trình tôi đã viết, nó xuất hiện tệp có kích thước chính xác như kích thước trước đó. Có ai khác có vấn đề này với GZipStream không?GZipStream trên dữ liệu lớn

Mã của tôi là như sau:

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

Các StreamSize là một giá trị UInt64 8 byte chứa kích thước của tập tin. tôi viết những 8 byte nguyên để bắt đầu của tập tin vì vậy tôi biết kích thước tập tin ban đầu. Writeblock có giá trị là 32kb (32768 byte). fromStream là luồng để lấy dữ liệu từ, trong trường hợp này, một FileStream. Là 8 byte infront của dữ liệu nén sẽ gây ra một vấn đề?

+0

Liệu việc mã của bạn trên các tập tin nhỏ hơn? –

+1

Bạn có thể xác nhận mã của bạn một cách chính xác nén các tập dữ liệu nhỏ hơn - một tệp văn bản ví dụ bạn biết thường nén tốt hay không ... – Nik

Trả lời

4

Tôi đã chạy thử nghiệm bằng cách sử dụng mã sau để nén và chạy mà không gặp sự cố trên tệp 7GB và 12GB (cả hai đều đã biết trước để nén "tốt"). Phiên bản này có phù hợp với bạn không?

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

Bạn đã xem documentation chưa?

Lớp GZipStream không thể giải nén dữ liệu dẫn đến hơn 8 GB dữ liệu không nén.

Bạn có thể cần phải tìm một thư viện khác sẽ hỗ trợ nhu cầu của bạn hoặc cố gắng chia nhỏ dữ liệu của bạn thành <=8GB các đoạn có thể được "khâu" một cách an toàn lại với nhau.

+2

Xin chào Austin, cảm ơn câu trả lời. Chương trình của tôi sẽ không được giải nén vì vậy tôi không nghĩ rằng vấn đề này? trừ khi nó là một giới hạn 8gb để nén quá. – Skintkingle

+0

Hmm ... nếu bạn cần nhiều hơn thế thì sao? Có các tùy chọn khác có sẵn không? Có vẻ kỳ lạ là một luồng sẽ có giới hạn như vậy. –

+0

Đó là nói về giải nén, OP đang nói về nén. –

-1

Mã của Austin Salonen không hoạt động đối với tôi (lỗi, lỗi 4GB).

Đây là cách thích hợp:

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

Xin vui lòng giải thích các downvote?! –