ionic zip - 将多个二进制文件中的数据添加到单个ZIP中

时间:2016-12-01 23:38:14

标签: c# ionic-framework zip

.NET 4.6.2

我从数据库中读取了一些(我知道它们是有效的)文件,然后尝试使用以下函数将它们组合成一个ZIP文件:

    public static byte[] CompressData(IList<ZipFileData> zipFileDatas)
    {
        var buffer = new byte[(int)zipFileDatas.Sum(z => z.Length)];

        using (var ms = new MemoryStream(buffer))
        {
            using (var zip = new ZipFile())
            {
                foreach (var zipFileData in zipFileDatas)
                    zip.AddEntry($"{zipFileData.FileName}.{zipFileData.FileType}", zipFileData.Data);

                zip.Save(ms);
            }

            return ms.ToArray();
        }
    }

参数是这些参数的集合:

public class ZipFileData
{
    public string FileName { get; set; }
    public string FileType { get; set; }  // Eg: PDF, JPG, XSLX
    public byte[] Data { get; set; }
    public long? Length { get; set; } // Length of the data
}

该函数似乎工作正常,但稍后当我将返回的byte []保存为“my.zip”并尝试打开它(从Windows 10)时,我收到错误“压缩(压缩)文件夹C: ... \ my.zip无效。

我正在尝试确定此功能(或其他一些代码)是否是问题的原因。

之前是否有人做过类似的事情或者可以验证函数是否正确?

1 个答案:

答案 0 :(得分:1)

您分配的缓冲区太小:

var buffer = new byte[(int)zipFileDatas.Sum(z => z.Length)];

非压缩的zip文件稍微大于内部文件的总和:每个zip条目都有一个标题(有时是一个页脚),并且在结尾处有一个“目录表” zip文件(中央目录)。

var ms = new MemoryStream(buffer)

会创建non-resizable memory stream有点太小。不幸的是,你错过的最后一个字节是最重要的:你可以找到中心目录的偏移量。没有它,你有一个损坏的zip文件。

要解决此问题,请使用resizable memory stream

var ms = new MemoryStream()