2016-12-01 29 views
1

.NET 4.6.2離子拉鍊 - 添加多個二進制文件數據到一個ZIP

我讀了一些(我知道它們是有效的)從一個數據庫,然後嘗試文件將它們合併成一個單一的ZIP文件使用下面的函數:

public static byte[] CompressData(IList<ZipFileData> zipFileDatas) 
    { 
     var buffer = new byte[(int)zipFileDatas.Sum(z => z.Length)]; 

     using (var ms = new MemoryStream(buffer)) 
     { 
      using (var zip = new ZipFile()) 
      { 
       foreach (var zipFileData in zipFileDatas) 
        zip.AddEntry($"{zipFileData.FileName}.{zipFileData.FileType}", zipFileData.Data); 

       zip.Save(ms); 
      } 

      return ms.ToArray(); 
     } 
    } 

的參數是它們的集合:

public class ZipFileData 
{ 
    public string FileName { get; set; } 
    public string FileType { get; set; } // Eg: PDF, JPG, XSLX 
    public byte[] Data { get; set; } 
    public long? Length { get; set; } // Length of the data 
} 

當我返回的byte []保存爲「my.zip」的功能似乎正常工作,但後來並嘗試打開它(從Windows 10),我得到錯誤「壓縮(壓縮)文件夾C:... \ my.zip無效。

我想確定這個函數(或其他代碼)是否是問題的原因。

有沒有人做過類似的事情,或者可以驗證函數是(正確)?

回答

1

你分配過小的緩衝器:

var buffer = new byte[(int)zipFileDatas.Sum(z => z.Length)]; 

非壓縮zip文件將稍微更大的是內部文件的總和:每個ZIP項都有一個頭(有時頁腳)和有壓縮文件末尾的「內容表」(中央目錄)。

var ms = new MemoryStream(buffer) 

將創建一個non-resizable memory stream有點太小。不幸的是,你錯過的最後幾個字節是最重要的字節:這就是你找到中央目錄的偏移量的地方。沒有它,你有一個損壞的zip文件。

要解決此問題,使用resizable memory stream

var ms = new MemoryStream() 
+0

大衛 - 謝謝你,工作一種享受。我確實知道這一點,但是如果你沒有預先分配一個Memory Stream的空間,我總是不確定發生了什麼。 –