2012-04-24 131 views
4

DotNetZip有一個奇怪的問題,我似乎無法找到解決方案。 我已經搜索了幾個小時,現在我找不到任何東西,所以在這裏。DotNetZip創建損壞的存檔(壞CRC)

var ms = new MemoryStream(); 
using (var archive = new Ionic.Zip.ZipFile()) { 
    foreach (var file in files) { 
     //        string  byte[] 
     var entry = archive.AddEntry(file.Name, file.Data); 
     entry.ModifiedTime = DateTime.Now.AddYears(10); // Just for testing 
    } 
    archive.Save(ms); 
} 
return ms.GetBuffer(); 

我需要添加修改的時間,這是相當重要的,但現在我只是有一個虛假的時間戳。

當我用WinRAR打開文件時,它說「存檔意外結束」。每個單獨的文件都有校驗和00000000,並且WinRAR表示「檔案文件格式未知或損壞」。我可以修復它,使其尺寸縮小20%,並使一切正常。但是這並不是很有用......

當我在添加所有條目後做出斷點時,我可以在zip.Entries中看到所有條目都有相同的壞CRC,但所有數據似乎都在那裏。 所以它不應該是我保存檔案的方式。

我在其他地方使用我的文件集沒有問題,這增加了DotNetZip的奇怪。那麼無論是或我誤解了一些東西:)

+2

'GetBuffer'肯定是錯誤的,因爲緩衝區通常比內容大。使用'ToArray()'。或者仔細處理消費代碼中未完全填充的緩衝區。 – CodesInChaos 2012-04-24 06:59:40

+0

我很高興我們得到了這一點。它實際上解決了這個問題。你可以添加該評論作爲答案,所以我可以接受它嗎? – Heki 2012-04-24 07:06:05

回答

6

GetBuffer肯定是錯誤的。它返回MemoryStream的內部緩衝區,它通常比實際的內容大。

要返回僅包含實際內容的數組,請使用ToArray()

或者你可以仔細處理消費代碼中未完全填充的緩衝區。這將減少GC壓力,因爲您不需要爲返回值分配一個全新的數組。

如果zip壓縮文件很大,我還會考慮直接保存到文件中,而不是將內存中的壓縮文件組合在一起。

+0

謝謝,CodeInChaos。你在這裏有一些好點。緩衝區的Handeling將刪除所有尾隨的0字節? – Heki 2012-04-24 07:17:27

+1

這取決於調用代碼。這將等於傳遞有效數據的長度,並對其進行適當處理。你不能認爲所有的'0'字節都是無效的,只有'ms.Length'之外的字節是無效的。 – CodesInChaos 2012-04-24 07:27:21