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

C#ZipOutputStream从输出流获取无效文件,c#,zipoutputstream,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();

我一直在使用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;
    }
public static byte[]CompressToZip(List fileItemList,int-zipLevel=3)
{
MemoryStream zipMemoryStream=新的MemoryStream();
ZipOutStream zOutput=新ZipOutStream(zipMemoryStream);
输出设置电平(zipLevel);
ICSharpCode.SharpZipLib.Checksums.Crc32 crc=新ICSharpCode.SharpZipLib.Checksums.Crc32();
foreach(fileItemList中的var文件)
{
ZipEntry条目=新ZipEntry(file.Item2);
entry.DateTime=DateTime.Now;
entry.Size=file.Item1.Length;
crc.Reset();
crc.Update(文件.Item1);
entry.Crc=Crc.Value;
zOutput.PUTNEXENTRY(条目);
Write(file.Item1,0,file.Item1.Length);
}
zOutput.IsStreamOwner=false;
zOutput.Finish();
zOutput.Close();
zipMemoryStream.Position=0;
字节[]zipedFile=zipMemoryStream.ToArray();
返回zipedFile;
}
该函数适用于包含一项的文件。但由于某种原因,当我有两个或更多的文件时,我在提取/打开它时会出错

PeaZip说:

存档文件不可读

温齐普说:

存储在此文件的本地标头中的压缩大小与存储在中心标头中的压缩大小不同

但这是踢球的人。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;
    }
public static byte[]CompressToZip(List fileItemList,int-zipLevel=3)
{
MemoryStream zipMemoryStream=新的MemoryStream();
ZipOutStream zOutput=新ZipOutStream(zipMemoryStream);
输出设置电平(zipLevel);
ICSharpCode.SharpZipLib.Checksums.Crc32 crc=新ICSharpCode.SharpZipLib.Checksums.Crc32();
foreach(fileItemList中的var文件)
{
ZipEntry条目=新ZipEntry(file.Item2);
entry.DateTime=DateTime.Now;
entry.Size=file.Item1.Length;
crc.Reset();
crc.Update(文件.Item1);
entry.Crc=Crc.Value;
zOutput.PUTNEXENTRY(条目);
var memStreamCurrentfile=newmemoryStream(file.Item1);
Copy(memStreamCurrentfile,zOutput,新字节[4096]);
zOutput.CloseEntry();
}
zOutput.IsStreamOwner=false;
zOutput.Finish();
zOutput.Close();
zipMemoryStream.Position=0;
字节[]zipedFile=zipMemoryStream.ToArray();
返回zipedFile;
}

算出了!似乎我设置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;
    }
public static byte[]CompressToZip(List fileItemList,int-zipLevel=3)
{
MemoryStream zipMemoryStream=新的MemoryStream();
ZipOutStream zOutput=新ZipOutStream(zipMemoryStream);
输出设置电平(zipLevel);
ICSharpCode.SharpZipLib.Checksums.Crc32 crc=新ICSharpCode.SharpZipLib.Checksums.Crc32();
foreach(fileItemList中的var文件)
{
ZipEntry条目=新ZipEntry(file.Item2);
entry.DateTime=DateTime.Now;
zOutput.PUTNEXENTRY(条目);
var memStreamCurrentfile=newmemoryStream(file.Item1);
Copy(memStreamCurrentfile,zOutput,新字节[4096]);
zOutput.CloseEntry();
}
zOutput.IsStreamOwner=false;
zOutput.Finish();
zOutput.Close();
zipMemoryStream.Position=0;
字节[]zipedFile=zipMemoryStream.ToArray();
返回zipedFile;
}

上的示例添加了一个
zipStream.CloseEntry()在每个条目之后。只是尝试了一下,还使用了StreamUtils.Copy()方法。还是同样的问题:(