C# ZipOutputStream 从输出流获取无效文件

mBr*_*024 3 c# zipoutputstream

我一直在使用 C# 的 SharpZip 库(版本 0.86.0)。我基本上用它来将许多文件打包到一个干净的 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;
    }
Run Code Online (Sandbox Code Playgroud)

该函数对于其中包含一项的文件效果很好。但由于某种原因,当我有两个或更多时,当我提取/打开它时,我会遇到错误。

豌豆拉链 说:

存档不可读

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;
    }
Run Code Online (Sandbox Code Playgroud)

mBr*_*024 5

弄清楚了!看来我设置的 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;
    }
Run Code Online (Sandbox Code Playgroud)