2010-06-18 39 views
7

Tôi có một số mã tải xuống các tệp đã nén và giải nén chúng. Vấn đề là, tôi không thể làm cho nó giải nén toàn bộ tập tin, nó chỉ đọc 4096 byte đầu tiên và sau đó khoảng 500 hơn.GZipStream không đọc toàn bộ tệp

Byte[] buffer = new Byte[4096]; 
int count = 0; 
FileStream fileInput = new FileStream("input.gzip", FileMode.Open, FileAccess.Read, FileShare.Read); 
FileStream fileOutput = new FileStream("output.dat", FileMode.Create, FileAccess.Write, FileShare.None); 
GZipStream gzipStream = new GZipStream(fileInput, CompressionMode.Decompress, true); 

// Read from gzip steam 
while ((count = gzipStream.Read(buffer, 0, buffer.Length)) > 0) 
{ 
    // Write to output file 
    fileOutput.Write(buffer, 0, count); 
} 

// Close the streams 
... 

Tôi đã kiểm tra tệp đã tải xuống; 13MB khi được nén và chứa một tệp XML. Tôi đã giải nén thủ công tệp XML và nội dung là tất cả ở đó. Nhưng khi tôi làm điều đó với mã này, nó chỉ xuất ra phần đầu của tệp XML.

Bất kỳ ai có bất kỳ ý tưởng nào tại sao điều này có thể xảy ra?

+0

Tôi nhớ nhận được vấn đề này khi tôi đang viết một thói quen giải nén. Tuy nhiên, tôi đã nhìn vào mã làm việc mà tôi đã kết thúc và nó trông giống như của bạn bên cạnh việc được bọc trong các khối 'sử dụng'. –

+3

Bạn có đang gọi phương thức Flush() không? – n535

+0

Đã cố gắng với Flush(), không trợ giúp. – Edgar

Trả lời

1

Tôi đã kết thúc bằng cách sử dụng tệp thực thi gzip để thực hiện giải nén thay vì GZipStream. Nó không thể xử lý các tập tin vì lý do nào đó, nhưng thực thi có thể.

+0

Bạn có thể đăng phiên bản cuối cùng của mình được không. Tôi muốn xem chính xác cách bạn sử dụng gzip thực thi. – ManInMoon

+0

Rất tiếc, tôi không có quyền truy cập vào mã nữa. Nó đã sử dụng lớp Process để gọi hàm gzip có thể thực thi được. Điều này có thể giúp: http://www.dotnetperls.com/7-zip – Edgar

4

EDIT

Cố gắng không rời khỏi GZipStream mở:

GZipStream gzipStream = new GZipStream(fileInput, CompressionMode.Decompress, 
                     false); 

hoặc

GZipStream gzipStream = new GZipStream(fileInput, CompressionMode.Decompress); 
+0

Có, tôi đã thử CopyTo(). Kết quả là như nhau. Tôi không biết tại sao nó không thể đọc xa hơn nó. – Edgar

+0

Đã thử sử dụng các câu lệnh; không thay đổi. – Edgar

+0

Đã cố gắng không rời khỏi GZipStream mở; không thay đổi. – Edgar

0

Bạn đang gọi Close hoặc Flush trên fileOutput? (Hoặc chỉ cần bọc nó trong một using, đó là khuyến cáo thực hành.) Nếu bạn không tập tin có thể không được flushed vào đĩa khi chương trình của bạn kết thúc.

+0

Tất cả 3 luồng đều bị đóng sau khi đọc xong. Vấn đề không phải là dữ liệu không được ghi chính xác vào tệp đầu ra, nhưng đọc() không đọc toàn bộ tệp đầu vào. Có thể có điều gì đó làm gián đoạn nó? Nó đọc số byte chính xác mỗi lần trước khi nó dừng lại, đó là tò mò. – Edgar

+0

Giá trị của 'đếm' sau lần đọc đầu tiên là gì? –

+0

Sau lần đọc đầu tiên là 4096, lần đọc thứ hai là 532 và sau đó dừng lại. – Edgar

1

Điều tương tự đã xảy ra với tôi. Trong trường hợp của tôi chỉ đọc lên đến 6 dòng và sau đó đến cuối tập tin. Vì vậy, tôi nhận ra rằng mặc dù phần mở rộng là gz, nhưng nó đã được nén bởi một thuật toán khác không được GZipStream hỗ trợ. Vì vậy, tôi đã sử dụng thư viện SevenZipSharp và nó đã hoạt động. Đây là mã của tôi

Bạn có thể sử dụng thư viện SevenZipSharp

using (var input = File.OpenRead(lstFiles[0])) 
{ 
    using (var ds = new SevenZipExtractor(input)) 
    { 
     //ds.ExtractionFinished += DsOnExtractionFinished; 

     var mem = new MemoryStream(); 
     ds.ExtractFile(0, mem); 

     using (var sr = new StreamReader(mem)) 
     { 
      var iCount = 0; 
      String line; 
      mem.Position = 0; 
      while ((line = sr.ReadLine()) != null && iCount < 100) 
      { 
       iCount++; 
       LstOutput.Items.Add(line); 
      } 

     } 
    } 
} 
Các vấn đề liên quan