2012-04-24 12 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で開くと、「Unexpected end of archive」と表示されます。個々のファイルにはチェックサム00000000があり、WinRARには「アーカイブは不明な形式か破損しています」と表示されます。私はそれを修理することができます。それはサイズを20%縮小し、すべてをOKにします。しかし、それは本当に便利ではありません。

すべてのエントリを追加した後にブレークポイントを作成すると、すべてのエントリに同じ不良CRCがありますが、すべてのデータがそこにあるように見えます。zip.Entries これは、問題のアーカイブを保存する方法であってはなりません。

私は問題なくDotNetZipに奇妙なファイルを追加しています。まあそれか私は何かを誤解しています:)

+2

'GetBuffer'は確かに間違っています、なぜならバッファはしばしば内容よりも大きいからです。 'ToArray()'を使ってください。または、消費コード内の不完全に満たされたバッファを注意深く処理します。 – CodesInChaos

+0

私はそれを途方に引いてしまったことをうれしく思っています。それは実際に問題を解決しました。そのコメントを回答として追加できますか?私はそれをそのまま受け入れることができますか? – Heki

答えて

6

GetBufferは間違いです。 MemoryStreamの内部バッファーを返します。実際の内容よりも大きいことがよくあります。

実際のコンテンツのみを含む配列を返すには、ToArray()を使用してください。

または、消費コードで不完全に満たされたバッファを慎重に処理できます。戻り値に新しい配列全体を割り当てる必要がないので、GCの負担が軽減されます。

ジップアーカイブが大きい場合は、アーカイブをメモリに組み立てる代わりに、ファイルに直接保存することも検討します。

+0

ありがとう、CodeInChaos。ここには良い点があります。バッファのハンドリングは、末尾の0バイトをすべて削除することでしょうか? – Heki

+1

呼び出しコードによって異なります。それは有効なデータの長さを過ぎて適切に扱うことになります。末尾の '0'バイトはすべて無効であるとみなすことはできず、' ms.Length'を超えたものだけを無効にすることはできません。 – CodesInChaos

関連する問題