31

我正在尝试使用一些字节数组数据动态创建一个 zip 流,并通过我的 MVC 操作将其下载。

但下载的文件在 Windows 中打开时总是出现以下损坏错误。

在此处输入图像描述

当我尝试从 7z 提取时出现此错误

在此处输入图像描述

但请注意,从 7z 中提取的文件没有损坏。

我正在使用ZipArchive,下面是我的代码。

    private byte[] GetZippedPods(IEnumerable<POD> pods, long consignmentID)
    {
        using (var zipStream = new MemoryStream())
        {
            //Create an archive and store the stream in memory.                
            using (var zipArchive = new ZipArchive(zipStream, ZipArchiveMode.Create, true))
            {
                int index = 1;
                foreach (var pod in pods)
                {                        
                    var zipEntry = zipArchive.CreateEntry($"POD{consignmentID}{index++}.png", CompressionLevel.NoCompression);                       
                    using (var originalFileStream = new MemoryStream(pod.ByteData))
                    {
                        using (var zipEntryStream = zipEntry.Open())
                        {
                            originalFileStream.CopyTo(zipEntryStream);
                        }
                    }
                }
                return zipStream.ToArray();
            }
        }
    }

    public ActionResult DownloadPOD(long consignmentID)
    {
        var pods = _consignmentService.GetPODs(consignmentID);
        var fileBytes = GetZippedPods(pods, consignmentID);
        return File(fileBytes, MediaTypeNames.Application.Octet, $"PODS{consignmentID}.zip");
    }

我在这里做错了什么。

任何帮助将不胜感激,因为我整天都在为此苦苦挣扎。

提前致谢

4

5 回答 5

46

移出zipStream.ToArray()使用zipArchive

你的问题的原因是流被缓冲了。有几种处理方法:

  • 您可以将流的AutoFlush属性设置为true.
  • .Flush()您可以在流上手动调用。

或者,因为它是MemoryStream并且您正在使用.ToArray(),您可以简单地允许首先关闭/处置流(我们通过将其移到外部来完成using)。

于 2017-12-08T04:57:18.537 回答
6

我处理 ZipArchive 并解决了错误

 public static byte[] GetZipFile(Dictionary<string, List<FileInformation>> allFileInformations)
    {

        MemoryStream compressedFileStream = new MemoryStream();
        //Create an archive and store the stream in memory.
        using (var zipArchive = new ZipArchive(compressedFileStream, ZipArchiveMode.Create, true))
        {
            foreach (var fInformation in allFileInformations)
            {
                var files = allFileInformations.Where(x => x.Key == fInformation.Key).SelectMany(x => x.Value).ToList();
                for (var i = 0; i < files.Count; i++)
                {
                    ZipArchiveEntry zipEntry = zipArchive.CreateEntry(fInformation.Key + "/" + files[i].FileName);

                    var caseAttachmentModel = Encoding.UTF8.GetBytes(files[i].Content);

                    //Get the stream of the attachment
                    using (var originalFileStream = new MemoryStream(caseAttachmentModel))
                    using (var zipEntryStream = zipEntry.Open())
                    {
                        //Copy the attachment stream to the zip entry stream
                        originalFileStream.CopyTo(zipEntryStream);
                    }
                }
            }
            //i added this line 
            zipArchive.Dispose();

            return compressedFileStream.ToArray();
        }
    }

public void SaveZipFile(){
        var zipFileArray = Global.GetZipFile(allFileInformations);
        var zipFile = new MemoryStream(zipFileArray);
        FileStream fs = new FileStream(path + "\\111.zip", 
        FileMode.Create,FileAccess.Write);
        zipFile.CopyTo(fs);
        zipFile.Flush();
        fs.Close();
        zipFile.Close();
}
于 2019-10-28T10:57:55.763 回答
0

我也遇到了这个问题,我发现我的问题不是存档本身的生成,而是我如何在 AngularJS 中处理我的 GET 请求。

这篇文章帮助了我:如何使用 Angular 下载 zip 文件

关键是添加responseType: 'arraybuffer'到我的 $http 调用中。

factory.serverConfigExportZIP = function () {
    return $http({
        url: dataServiceBase + 'serverConfigExport',
        method: "GET",
        responseType: 'arraybuffer'
    })
};
于 2018-08-10T19:06:30.363 回答
0

您可以删除“使用”并使用 Dispose 和 Close 方法,这对我有用

...
zip.Dispose();
zipStream.Close();
return zipStream.ToArray();
于 2020-06-04T08:27:27.117 回答
0

我知道这是一个 C# 问题,但对于托管 C++,请在完成后删除 ZipArchive^ 以修复错误。

ZipArchive^ zar = ZipFile::Open(starget, ZipArchiveMode::Create);
ZipFileExtensions::CreateEntryFromFile(zar, sfile1, "file.txt");
ZipFileExtensions::CreateEntryFromFile(zar, sfile2, "file2.txt");
delete zar;
于 2020-12-10T21:51:02.343 回答