使用System.IO.Compression创建无效的zip文件

Cés*_*nço 15 c# asp.net-mvc system.io.compression

我正在尝试创建一个包含一个或多个文件的zip文件.
我正在使用.NET framework 4.5,更具体地说是System.IO.Compression命名空间.
目标是允许用户通过ASP.NET MVC应用程序下载zip文件.
正在生成zip文件并将其发送到客户端但是当我尝试通过双击它来打开它时,我收到以下错误:
Windows无法打开该文件夹.压缩(zipped)文件夹...无效.
这是我的代码:

[HttpGet]
public FileResult Download()
{
    var fileOne = CreateFile(VegieType.POTATO);
    var fileTwo = CreateFile(VegieType.ONION);
    var fileThree = CreateFile(VegieType.CARROT);

    IEnumerable<FileContentResult> files = new List<FileContentResult>() { fileOne, fileTwo, fileThree };
    var zip = CreateZip(files);

    return zip;
}

private FileContentResult CreateFile(VegieType vType)
{
    string fileName = string.Empty;
    string fileContent = string.Empty;

    switch (vType)
    {
        case VegieType.BATATA:
            fileName = "batata.csv";
            fileContent = "THIS,IS,A,POTATO";
            break;
        case VegieType.CEBOLA:
            fileName = "cebola.csv";
            fileContent = "THIS,IS,AN,ONION";
            break;
        case VegieType.CENOURA:
            fileName = "cenoura.csv";
            fileContent = "THIS,IS,A,CARROT";
            break;
        default:
            break;
    }

    var fileBytes = Encoding.GetEncoding(1252).GetBytes(fileContent);
    return File(fileBytes, MediaTypeNames.Application.Octet, fileName);
}

private FileResult CreateZip(IEnumerable<FileContentResult> files)
{
    byte[] retVal = null;

    if (files.Any())
    {
        using (MemoryStream zipStream = new MemoryStream())
        {
            using (ZipArchive archive = new ZipArchive(zipStream, ZipArchiveMode.Create, false))
            {
                foreach (var f in files)
                {
                    var entry = archive.CreateEntry(f.FileDownloadName, CompressionLevel.Fastest);
                    using (var entryStream = entry.Open())
                    {
                        entryStream.Write(f.FileContents, 0, f.FileContents.Length);
                        entryStream.Close();
                    }
                }

                zipStream.Position = 0;
                retVal = zipStream.ToArray();
            }
        }
    }

    return File(retVal, MediaTypeNames.Application.Zip, "horta.zip");
}
Run Code Online (Sandbox Code Playgroud)

任何人都可以说明为什么当我双击它时,Windows说我的zip文件无效.
最后一点考虑,我可以用7-Zip打开它.

Mic*_*inc 22

在ZipArchive对象被释放后,您需要通过ToArray获取MemoryStream缓冲区.否则,最终会导致存档损坏.

请注意,我已经更改了ZipArchive构造函数的参数,以便在添加条目时保持打开状态.

当ZipArchive正在处理时会有一些校验和,所以如果您之前读过MemoryStream,它仍然是不完整的.

    private FileResult CreateZip(IEnumerable<FileContentResult> files)
    {
        byte[] retVal = null;

        if (files.Any())
        {
            using (MemoryStream zipStream = new MemoryStream())
            {
                using (ZipArchive archive = new ZipArchive(zipStream, ZipArchiveMode.Create, true))
                {
                    foreach (var f in files)
                    {
                        var entry = archive.CreateEntry(f.FileDownloadName, CompressionLevel.Fastest);
                        using (BinaryWriter writer = new BinaryWriter(entry.Open()))
                        {                                   
                            writer.Write(f.FileContents, 0, f.FileContents.Length);
                            writer.Close();
                        }
                    }

                    zipStream.Position = 0;
                }
                retVal = zipStream.ToArray();
            }
        }

        return File(retVal, MediaTypeNames.Application.Zip, "horta.zip");
    }
Run Code Online (Sandbox Code Playgroud)

  • 在我的测试中,似乎不需要创建MemoryStream缓冲区(这很好,因为我正在创建14GB的zip文件备份),我只需要显式调用Dispose方法ZipArchive。这是在VS2017社区.NET(4.6)控制台项目上。 (2认同)