gpt4 book ai didi

c# - 使用 System.IO.Compression 创建后无效的 zip 文件

转载 作者:可可西里 更新时间:2023-11-01 07:53:59 31 4
gpt4 key购买 nike

我正在尝试创建一个包含一个或多个文件的 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");
}

谁能解释一下为什么当我双击我的 zip 文件时 Windows 说它无效。
最后考虑一下,我可以使用 7-Zip 打开它。

最佳答案

在处理 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");
}

关于c# - 使用 System.IO.Compression 创建后无效的 zip 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40175391/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com