使用System.IO.Compression创建的zip文件无效 [英] Invalid zip file after creating it with System.IO.Compression
问题描述
我正在尝试创建一个包含一个或多个文件的zip文件.
我正在使用.NET Framework 4.5,更具体地说是使用System.IO.Compression命名空间.
目的是允许用户通过ASP.NET MVC应用程序下载zip文件.
该zip文件正在生成并发送到客户端,但是当我尝试通过双击打开它时,出现以下错误:
Windows无法打开该文件夹.压缩(压缩)文件夹...无效.
这是我的代码:
I'm trying to create a zip file that contains one or more files.
I'm using the .NET framework 4.5 and more specifically System.IO.Compression namespace.
The objective is to allow a user to download a zip file through a ASP.NET MVC application.
The zip file is being generated and sent to the client but when I try to open it by doing double click on it I get the following error:
Windows cannot open the folder.
The compressed (zipped) folder ... is invalid.
Here's my code:
[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");
}
任何人都可以阐明为什么Windows双击双击后我的zip文件无效.
最后,我可以使用7-Zip打开它.
Can anyone please shed some light on why is windows saying that my zip file is invalid when I double click on it.
A final consideration, I can open it using 7-Zip.
推荐答案
在处置ZipArchive对象之后,需要通过ToArray获取MemoryStream缓冲区.否则,您最终将导致存档损坏.
You need to get the MemoryStream buffer via ToArray after the ZipArchive object gets disposed. Otherwise you end up with corrupted archive.
并且请注意,我已更改ZipArchive构造函数的参数,以在添加条目时使其保持打开状态.
And please note that I have changed the parameters of ZipArchive constructor to keep it open when adding entries.
在处理ZipArchive时会有一些校验和,因此如果您之前阅读过MemoryStream,它仍然不完整.
There is some checksumming going on when the ZipArchive is beeing disposed so if you read the MemoryStream before, it is still incomplete.
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");
}
这篇关于使用System.IO.Compression创建的zip文件无效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!