【问题标题】:MVC Core ZipArchive Is InvalidMVC 核心 ZipArchive 无效
【发布时间】:2017-06-17 15:07:46
【问题描述】:

我正在 MVC Core 下的 Web API 调用中创建一个 zip 文件,但 Windows 无法打开生成的文件,声称它无效。

这是创建存档的代码:

ZipArchive archive = new ZipArchive( archiveMS, ZipArchiveMode.Create, true );

// loop over a series of Azure blobs which contain text
foreach( BlobPathInfo curBPI in model.Paths )
{
    // AzureBlobFile is a wrapper for CloudBlockBlob
    AzureBlobFile blobFile = blobFolder.File( curBPI.BlobPath.FileName );
    Stream blobStream = blobFile.OpenRead();

    ZipArchiveEntry entry = archive.CreateEntry( zipFolderPath.ToString() );

    using( Stream zipStream = entry.Open() )
    {
        blobStream.CopyTo( zipStream );
    }
}

archive.Dispose();
archiveMS.Seek( 0, SeekOrigin.Begin );

return new FileStreamResult( archiveMS, "application/zip" );

此 WebAPI 方法从 Angular 脚本调用并转换为链接到元素的客户端 blob:

// downloadFiles does a POST request and returns a promise
downloadFiles( params )
.then( function( success ) {
    var linkElement = document.createElement( 'a' );
    var blob = new Blob( [success.data], { type: 'application/zip' } );
    var url = window.URL.createObjectURL( blob );

    linkElement.setAttribute( 'href', url );
    linkElement.setAttribute( 'download', fileName );

    var clickEvent = new MouseEvent( 'click',
    {
        view: window,
        bubbles: true,
        cancelable: false
    } );

    linkElement.dispatchEvent( clickEvent );

这一切都是因为存档是在服务器上创建的,下载到客户端,然后通过文件保存对话框保存。但就 Windows 而言,磁盘上生成的存档是无效的。

windows 错误信息没有帮助,基本上只是声明文件无效。但我确实注意到另外两件事可能很重要:

1) 如果我没有在服务器上的 zip 存档中创建条目——如果我只是创建存档并下载它——它会在 Windows 下正确打开(当然,显示它没有内容/条目)。

2) 在检查错误日志时,我注意到以下内容:

日志名称:应用程序来源:IIS Express 日期:
2017 年 1 月 31 日下午 4:20:15 事件 ID:2264 任务类别:无级别:
警告关键字:经典用户:N/A 计算机:
Muddlehead 描述:指定用于缓存压缩的目录 内容 C:\Users\Mark\AppData\Local\Temp\iisexpress\IIS 临时 压缩文件\Clr4IntegratedAppPool 无效。静态压缩 正在被禁用。事件 XML:
2264 3 0 0x80000000000000 90672 应用 糊涂蛋 C:\Users\Mark\AppData\Local\Temp\iisexpress\IIS 临时压缩文件\Clr4IntegratedAppPool 03000000

关于如何解决这个问题的想法?

【问题讨论】:

    标签: asp.net-web-api asp.net-core asp.net-core-mvc


    【解决方案1】:

    在使用 ZipArchive 时,您应该写 'using'。 当 IDisposible 运行时,它会正确完成您的文件。

    byte [] zipBytes;
    using (MemoryStream ms = new MemoryStream())
    {
        var file1 = Encoding.ASCII.GetBytes("Hello,world!");
        using (var archive = new ZipArchive(ms, ZipArchiveMode.Create, true))
        {
            var zipArchiveEntry = archive.CreateEntry("file1.txt",     CompressionLevel.Fastest);
            using (var zipStream = zipArchiveEntry.Open()) 
              { zipStream.Write(file1, 0, file1.Length); }
    
        }
        zipBytes = ms.ToArray(); // good place to assign
    }
    return File(zipBytes, "application/zip", "Archive.zip");
    

    这样写的时候拉链不好

    byte [] zipBytes;
    using (MemoryStream ms = new MemoryStream())
    {
        var file1 = Encoding.ASCII.GetBytes("Hello,world!");
        using (var archive = new ZipArchive(ms, ZipArchiveMode.Create, true))
        {
            var zipArchiveEntry = archive.CreateEntry("file1.txt",     CompressionLevel.Fastest);
            using (var zipStream = zipArchiveEntry.Open()) 
            {
               zipStream.Write(file1, 0, file1.Length);
            }
            zipBytes = ms.ToArray(); //bad place to assign
        }
    
    }
    return File(zipBytes, "application/zip", "Archive.zip");
    

    【讨论】:

    • 无需处理内存流。删除内存流上的using 并将其传递给File 结果。存档的leaveOpen 参数为真,这意味着它不会处理内存流。创建字节数组意味着您将在释放流之前使用双倍内存。
    • 是的,你完全正确。但我使用 zipBytes 来展示 ZipArchive 的功能在哪里
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-14
    • 1970-01-01
    • 2020-08-04
    • 1970-01-01
    相关资源
    最近更新 更多