2013-03-11 68 views
19

私は、DotNetZipで圧縮されたときにununzipableアーカイブを作成する奇妙なファイルがあります。私が7zipで解凍しようとすると失敗しますCRC failed in 'AjaxControlToolkit.dll'. File is broken. 7zipで手動で解凍すると問題はありません。DotNetZip BadReadException on .Extract

DotNetZipが単純なバイナリファイルを正しく圧縮できないシナリオを見つけたのは誰ですか?または私は間違ってDotNetZipを使用していますか?

https://dl.dropbox.com/u/65419748/AjaxControlToolkit.dll

using System.IO; 
using Ionic.Zip; 

namespace ConsoleApplication1 
{ 
    public class Program 
    { 
     public static void Main(string[] args) 
     { 
      var source = new FileInfo(@"C:\ZipDemo\AjaxControlToolkit.dll"); 
      var target = new FileInfo(Path.ChangeExtension(source.FullName, "zip")); 
      var folder = new DirectoryInfo(Path.ChangeExtension(source.FullName, null)); 

      if (target.Exists) 
       target.Delete(); 

      if (folder.Exists) 
       folder.Delete(true); 

      using (var zip = new ZipFile(target.FullName)) 
      { 
       zip.AddFile(source.FullName, string.Empty); 
       zip.Save(); 
      } 

      using (var zip = new ZipFile(target.FullName)) 
       zip.ExtractAll(folder.FullName); 
     } 
    } 
} 

例外:

Unhandled Exception: Ionic.Zip.BadReadException: bad read of entry AjaxControlToolkit.dll from compressed archive. 
    at Ionic.Zip.ZipEntry._CheckRead(Int32 nbytes) 
    at Ionic.Zip.ZipEntry.ExtractOne(Stream output) 
    at Ionic.Zip.ZipEntry.InternalExtract(String baseDir, Stream outstream, String password) 
    at Ionic.Zip.ZipFile._InternalExtractAll(String path, Boolean overrideExtractExistingProperty) 
    at Ionic.Zip.ZipFile.ExtractAll(String path) 
    at ConsoleApplication1.Program.Main(String[] args) in C:\ZipDemo\ConsoleApplication1\ConsoleApplication1\Program.cs:line 27 

編集:

私は余分なバイトを追加した場合、それはうまく動作しますが、それが受け入れ可能な解決策ではありません。 + 1なしで失敗します。

var bytes = new byte[source.Length + 1]; 
File.ReadAllBytes(source.FullName).CopyTo(bytes, 0); 
zip.AddEntry(source.Name, bytes); 

更新:

はあきらめたとSharpZipLibに切り替え、それは簡単なエキスに爆破しないように、しかし確かDotNetZipと間違っていたかを知るためにいいだろう、それはよりよいAPIを持っています。

アップデート2:ファイルの長さについて

何かが、それは1179647および1179649バイトはzip圧縮され、正しく解凍し、爆破ます。

var source = new FileInfo(@"C:\ZipDemo\foo.txt"); 
using (var writer = source.CreateText()) 
    writer.Write(new string('a', 1179648)); 
+0

そして、あなたはいくつかの他のツールとそれを解凍しようとした場合、何が、たとえば、WinRarのをどうなりますか? – Tigran

+0

@Tigranは、さまざまなエラーが発生します。つまり、Windowsの抽出機能を使用すると、0x80004005というエラーが発生します。 –

+0

System.IO.Compressionの.net 4.5からZipArchiveを試して、同じ問題が発生していないかどうかを確認してください。バグかもしれない。 –

答えて

15

dllのサイズは53 * 128k(6954496/131072 = 53)です。DotNetZipには、https://dotnetzip.codeplex.com/workitem/14087というバグがあります。ちょうどあなたのコード内で使用します。

zip.ParallelDeflateThreshold = -1; 

私はそれが今完璧に働いて、たくさんのファイルのために、この問題を持っていた;)

+0

それは同様に働いた! ありがとうalot :) – Rida

+0

これは、C#4.5ファイル圧縮メソッドでも同じ問題を解決します:) –

+1

ありがとう!これは簡単な解決策であり、私にとっては十分です。以下の@laktakで提案されている修正プログラムでコンパイルするのは、おそらくより良いオプションですが、実際にはパラレルデフレートの最適化が必要な場合を除き、おそらく不要です。公式のコードレポが2011年から非アクティブになっているように思われるのは残念です。更新が進んでいるかどうかを確認してください。 – Chaser324

2

私はこれを試してみました -

  • あなたのコードを実行しますDotNetZip
  • の最新バージョンをインストールします。
  • この後BadReadException

を手に入れた -

  • DotNetZipの古いバージョン(1.9)をインストールします。 (Install-Package DotNetZip -Version 1.9
  • コードを実行する
  • コードは正常に動作します。

これはバグでしょうか?

+0

そのように見える、バグを提出http://dotnetzip.codeplex.com/workitem/16092 CodePlex自体がボルケージされていて、作業項目の説明を表示していないように見えるかもしれません。 –

+1

Cool。私が働くことができたサンプルであなたのバグを更新しました。誰でもトラブルシューティングに役立つはずです。 –

+0

それは解決策ではありません!あなたがバージョンを変更すると、サイズが変化しているので、今は問題が見えません。しかし、次回のアップデートでは、問題が再び発生する可能性があります。 – Xaruth

4

これはバグです。Zlib\ParallelDeflateOutputStream.csに修正することができます。

変更

} while (doAll && (_lastWritten != _latestCompressed)); 

} while (doAll && (_lastWritten != _lastFilled)); 

に詳細はhttps://dotnetzip.codeplex.com/workitem/14087を参照してください。