none
DotNetZIP で作成した圧縮ファイルの解凍に失敗する RRS feed

  • 質問

  • お世話になります。

    C#・Windows7やWindows2008環境にて

    DotNetZIP ライブラリ(Ionic.Zip.dll:バージョン1.9.1.8)でZIPファイルを圧縮したところ

    以下のようなC#のソースで、あるファイルを圧縮した際にZIPファイル自体は正常に作成されますが

    LHmeltなど一般的な解凍ソフトなどで解凍しようとすると、「CRCが一致しません。」といったエラーが出力され

    正常に解凍できないといった事象が発生いたします。

    try
       {
        // ZIPクラスをインスタンス化
        ZipFile zip = new ZipFile(Encoding.GetEncoding("shift_jis"));

        // 圧縮レベルを設定
        zip.CompressionLevel = CompressionLevel.BestCompression;

        // ファイル名を設定

        for (int i = 0; i < fileList.Count; i++)
        {
         // 圧縮ファイルにはルートにファイルを作成する。
         zip.AddFile(fileList[i].ToString(), string.Empty);
        }

        zip.Save(fileName);

       }
       catch (Exception ex)
       {
        // 圧縮ファイル作成失敗
     …ログを出力…

        return false;
       }

    該当の圧縮元ファイル(CSVファイル形式)はSJISコード・改行:CR+LFで作成されており

    テキストエディタ等でも問題なく参照できますし、試しに1バイト追加・1バイト削除や1行追加・1行削除など

    加工を行うと、正常に解凍できるZIPファイルが作成されます。

    よって、該当の圧縮元ファイル内容(データパターン)の場合のみCRCエラーが発生すると考えられます。

    このような事象について御存知のかた、もしくは本内容の原因ならびに対処方法をご存じのかたが

    いらっしゃいましたらご教示頂ければ幸いです。

    2014年8月29日 9:11

回答

  • DotNetZip にはある程度以上のサイズであり、特定の数値の倍数となるサイズのファイルを圧縮すると、ZIP ファイルとして壊れるという不具合があります。
    たぶん、デフォルトだと 524,288 バイトを超えて、65,536 の倍数にちょうどぴったしになるだったかな…。

    (この不具合を引いているのであれば、ZipFile の ParallelDeflateThreshold を int.MaxValue とか、現実的にないファイルサイズにしてしまえば回避できるかも)

    • 回答の候補に設定 星 睦美 2014年9月1日 1:32
    • 回答としてマーク 星 睦美 2014年9月8日 2:33
    2014年8月29日 16:58
    モデレータ

すべての返信

  • DotNetZIPライブラリの問題であれば、DotNetZIPに問い合わせた方が情報も得られると思いますが…。

    ちなみに.NET 4.5からSystem.IO.Compression名前空間ZipArchiveクラスなどが用意されたのでDotNetZIPライブラリを使わなくてもZIPファイルを作れるようになりました。

    2014年8月29日 10:19
  • ご返信ありがとうございます。

    DotNetZIPにも問合せを実施しようとしておりますが…提供元であるCodePlex がMicrosoftの open source projectということもあり、以前本コミュニティで類似の質問がありましたので、有識者が閲覧される可能性があるかと思い投稿させて頂きました。

    .NET4.5からはクラスが用意されているんですね。

    ただ本APを稼動させるサーバに.NET4.5を搭載できないので別の策を考える必要がありますので…今後の参考とさせて頂きます。

    情報ありがとうございました。

    2014年8月29日 11:27
  • DotNetZip にはある程度以上のサイズであり、特定の数値の倍数となるサイズのファイルを圧縮すると、ZIP ファイルとして壊れるという不具合があります。
    たぶん、デフォルトだと 524,288 バイトを超えて、65,536 の倍数にちょうどぴったしになるだったかな…。

    (この不具合を引いているのであれば、ZipFile の ParallelDeflateThreshold を int.MaxValue とか、現実的にないファイルサイズにしてしまえば回避できるかも)

    • 回答の候補に設定 星 睦美 2014年9月1日 1:32
    • 回答としてマーク 星 睦美 2014年9月8日 2:33
    2014年8月29日 16:58
    モデレータ
  • ご回答ありがとうございます。

    内容について確認したところ、ご指摘にあるようにファイルサイズは、524,288バイト以上でかつ65536バイトの倍数に合致しておりました。

    よって記載頂いた不具合を見事に引いてしまっているものと思います。

    CodeFlexのサイトを見る限り…記事:16815・15806・14087(いずれもworkitem配下)あたりが

    この事象に該当しそうかと存じます。

    今回回避策として記載頂いたParallelDeflateThreshold の値をint.Valueもしくは-1(-1だとマルチスレッド処理しないとありましたので…)で確認してみたいと思います。

    ありがとうございました。

    2014年9月1日 1:07