1

私は C# の SharpZip ライブラリ (バージョン 0.86.0) をいじっています。私は基本的に、多数のファイルを 1 つのクリーンな zip ファイルにパッケージ化するために使用しています。zip ファイルのバイト配列を生成する関数は次のようになります。

public static byte[] CompressToZip(List<Tuple<byte[], string>> fileItemList, int zipLevel = 3)
{
        MemoryStream zipMemoryStream = new MemoryStream();

        ZipOutputStream zOutput = new ZipOutputStream(zipMemoryStream);
        zOutput.SetLevel(zipLevel);

        ICSharpCode.SharpZipLib.Checksums.Crc32 crc = new ICSharpCode.SharpZipLib.Checksums.Crc32();

        foreach (var file in fileItemList)
        {
            ZipEntry entry = new ZipEntry(file.Item2);
            entry.DateTime = DateTime.Now;
            entry.Size = file.Item1.Length;

            crc.Reset();
            crc.Update(file.Item1);

            entry.Crc = crc.Value;

            zOutput.PutNextEntry(entry);
            zOutput.Write(file.Item1, 0, file.Item1.Length);
        }

        zOutput.IsStreamOwner = false;
        zOutput.Finish();
        zOutput.Close();
        zipMemoryStream.Position = 0;

        byte[] zipedFile = zipMemoryStream.ToArray();
        return zipedFile;
    }

この関数は、1 つのアイテムを含むファイルに対して正常に機能します。しかし、何らかの理由で2つ以上ある場合、抽出/開くときにエラーが発生します。

PeaZip は次のように述べています。

アーカイブを読み取れません

WinZip は次のように述べています。

このファイルのローカル ヘッダーに格納されている圧縮サイズは、中央ヘッダーに格納されている圧縮サイズと同じではありません

しかし、ここにキッカーがあります。Windows 8 アーカイブ ツールは、ファイルに対して問題なく動作します。WinZip エラーのようなものは、ファイルをストリームに間違って書き込んでいると思わせます。しかし、それは私にはうまく見えます。これをどうすればいいのかわからない..

編集

codemonkeys 入力からの私の変更は次のとおりです。私には良く見えますが、それでも同じエラーが発生します

public static byte[] CompressToZip(List<Tuple<byte[], string>> fileItemList, int zipLevel = 3)
{
        MemoryStream zipMemoryStream = new MemoryStream();

        ZipOutputStream zOutput = new ZipOutputStream(zipMemoryStream);
        zOutput.SetLevel(zipLevel);

        ICSharpCode.SharpZipLib.Checksums.Crc32 crc = new ICSharpCode.SharpZipLib.Checksums.Crc32();

        foreach (var file in fileItemList)
        {
            ZipEntry entry = new ZipEntry(file.Item2);
            entry.DateTime = DateTime.Now;
            entry.Size = file.Item1.Length;

            crc.Reset();
            crc.Update(file.Item1);

            entry.Crc = crc.Value;

            zOutput.PutNextEntry(entry);
            var memStreamCurrentfile = new MemoryStream(file.Item1);
            StreamUtils.Copy(memStreamCurrentfile, zOutput, new byte[4096]);
            zOutput.CloseEntry();
        }

        zOutput.IsStreamOwner = false;
        zOutput.Finish();
        zOutput.Close();
        zipMemoryStream.Position = 0;

        byte[] zipedFile = zipMemoryStream.ToArray();
        return zipedFile;
    }
4

1 に答える 1

2

理解した!Crcとファイルエントリのサイズを設定することが問題だったようです。それらを定義するのに役立つと思いました。私は間違っていたと思います。すべての人が楽しめる最終的なコードは次のとおりです。

public static byte[] CompressToZip(List<Tuple<byte[], string>> fileItemList, int zipLevel = 3)
    {
        MemoryStream zipMemoryStream = new MemoryStream();
        ZipOutputStream zOutput = new ZipOutputStream(zipMemoryStream);
        zOutput.SetLevel(zipLevel);
        ICSharpCode.SharpZipLib.Checksums.Crc32 crc = new ICSharpCode.SharpZipLib.Checksums.Crc32();
        foreach (var file in fileItemList)
        {
            ZipEntry entry = new ZipEntry(file.Item2);
            entry.DateTime = DateTime.Now;
            zOutput.PutNextEntry(entry);
            var memStreamCurrentfile = new MemoryStream(file.Item1);
            StreamUtils.Copy(memStreamCurrentfile, zOutput, new byte[4096]);
            zOutput.CloseEntry();
        }
        zOutput.IsStreamOwner = false;
        zOutput.Finish();
        zOutput.Close();
        zipMemoryStream.Position = 0;

        byte[] zipedFile = zipMemoryStream.ToArray();
        return zipedFile;
    }
于 2015-01-03T20:34:51.060 に答える