【问题标题】:Azure download blobs, create zip and send to userAzure 下载 blob,创建 zip 并发送给用户
【发布时间】:2016-06-12 13:51:22
【问题描述】:

我正在使用this 解决方案来下载文件、压缩并发送给用户,(Azure blobs)。

这是我迄今为止想出的:

    public void DownloadImages(DownloadImagesModel model)
    {
        if (ModelState.IsValid && model.ImageIDs != null && model.ImageIDs.Count > 0)
        {
            var currentUser = _claimService.GetCurrentClaimsIdentity(TimeZoneExtensions.GetCurrentDate());

            var images = _fileService.GetImages(currentUser.CompanyID, model.ImageIDs).ToList();

            if (images != null && images.Count > 0)
            {
                string imageContainerURL = _fileService.GetImageContainerURL(currentUser.CompanyID) + currentUser.ImageContainerToken;

                using (var zipOutputStream = new ZipOutputStream(Response.OutputStream))
                {
                    zipOutputStream.SetLevel(0); // 0 - store only to 9 - means best compression
                    Response.BufferOutput = false;
                    Response.AddHeader("Content-Disposition", "attachment; filename=" + "zipFileName.rar");
                    Response.ContentType = "application/octet-stream";

                    foreach (var image in images)
                    {
                        if (image.ImageLinks != null)
                        {
                            List<ImageLinkModel> imageLinks = new List<ImageLinkModel>();

                            if (model.FormatID == 0)
                                imageLinks = image.ImageLinks.ToList();
                            else
                                imageLinks = image.ImageLinks.Where(m => m.FormatID == model.FormatID).ToList();

                            if (imageLinks != null && imageLinks.Count > 0)
                            {
                                //Every image has multiple blobs for different sizes
                                foreach (var link in imageLinks)
                                {
                                    CloudBlockBlob blob = _fileService.GetBlob(imageContainerURL, link.BlobName);

                                    var entry = new ZipEntry(image.ImageName)
                                    {
                                        DateTime = TimeZoneExtensions.GetCurrentDate(),
                                        Size = blob.Properties.Length
                                    };

                                    zipOutputStream.PutNextEntry(entry);

                                    //Download
                                    blob.DownloadToStream(zipOutputStream);

                                    Response.Flush();

                                    if (!Response.IsClientConnected)
                                    {
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    zipOutputStream.Finish();
                    zipOutputStream.Close();
                }

                Response.End();
            }
        }
    }

当我打开下载的 zip 文件时,我得到:

存档意外结束。

压缩包应该包含三个文件,但只包含一个。大小也是0..

我错过了什么?

编辑 1

命名时需要指定.rar类型吗?

我不需要为流设置位置吗?

我是否正确定位了 Flush、Finish、Close 和 End 函数?

编辑 2

这段代码应该可以工作!?

    public ActionResult DownloadImages(DownloadImagesModel model)
    {
        if (ModelState.IsValid && model.ImageIDs != null && model.ImageIDs.Count > 0)
        {
            var currentUser = _claimService.GetCurrentClaimsIdentity(TimeZoneExtensions.GetCurrentDate());

            var images = _fileService.GetImages(currentUser.CompanyID, model.ImageIDs).ToList();

            if (images != null && images.Count > 0)
            {
                var cloudStorageAccount = new CloudStorageAccount(new StorageCredentials("name", "pw"), true);
                var container = cloudStorageAccount.CreateCloudBlobClient().GetContainerReference("images-1");

                using (var zipOutputStream = new ZipOutputStream(Response.OutputStream))
                {
                    foreach (var image in images)
                    {
                        if (image.ImageLinks != null)
                        {
                            List<ImageLinkModel> imageLinks = new List<ImageLinkModel>();

                            if (model.FormatID == 0)
                                imageLinks = image.ImageLinks.ToList();
                            else
                                imageLinks = image.ImageLinks.Where(m => m.FormatID == model.FormatID).ToList();

                            if (imageLinks != null && imageLinks.Count > 0)
                            {
                                zipOutputStream.SetLevel(0);

                                var blob = container.GetBlockBlobReference(imageLinks.First().BlobName);

                                var entry = new ZipEntry(imageLinks.First().BlobName);
                                zipOutputStream.PutNextEntry(entry);

                                //Download
                                blob.DownloadToStream(zipOutputStream);
                            }
                        }
                    }

                    zipOutputStream.Finish();
                    zipOutputStream.Close();
                }

                Response.BufferOutput = false;
                Response.AddHeader("Content-Disposition", "attachment; filename=" + "zipFileName.zip");
                Response.ContentType = "application/octet-stream";
                Response.Flush();
                Response.End();
                return null;
            }
        }

        return null;
    }

【问题讨论】:

  • 为什么在阅读第一个 blob 后刷新响应?在读取所有 blob 之后,您不应该这样做吗?
  • 这是个好问题。我实际上只是跟随其他人的实施。我将冲洗移动到 .finish 和 close 函数之前,但它仍然给我同样的问题..
  • 您可以尝试将blob.DownloadToStream(zipOutputStream); 放在zipOutputStream.PutNextEntry(entry); 之前,并在zipOutputStream.Close() 之后刷新响应,看看是否有什么不同?
  • 例外:附加信息:没有打开的条目。尝试下载到流时,(blob.DownloadToStream(zipOutputStream))
  • 我以为读入流时,它的位置没有重置为0...它在流的最后一位...您是否尝试将流的位置设置回0(在您尝试读取流之前)?

标签: c# asp.net asp.net-mvc azure


【解决方案1】:

我能够创建一个 zip 文件并使用以下代码下载它:

    public ActionResult Download()
    {
        var cloudStorageAccount = new CloudStorageAccount(new StorageCredentials("account-name", "account-key"), true);
        var container = cloudStorageAccount.CreateCloudBlobClient().GetContainerReference("test");
        var blobFileNames = new string[] { "file1.png", "file2.png", "file3.png", "file4.png" };
        using (var zipOutputStream = new ZipOutputStream(Response.OutputStream))
        {
            foreach (var blobFileName in blobFileNames)
            {
                zipOutputStream.SetLevel(0);
                var blob = container.GetBlockBlobReference(blobFileName);
                var entry = new ZipEntry(blobFileName);
                zipOutputStream.PutNextEntry(entry);
                blob.DownloadToStream(zipOutputStream);
            }
            zipOutputStream.Finish();
            zipOutputStream.Close();
        }
        Response.BufferOutput = false;
        Response.AddHeader("Content-Disposition", "attachment; filename=" + "zipFileName.zip");
        Response.ContentType = "application/octet-stream";
        Response.Flush();
        Response.End();
        return null;
    }

【讨论】:

  • 我的代码和你一模一样,但我的 zip 仍然损坏。当我调试并将鼠标悬停在 ZipOutputStream 上时,我遇到了几个错误。你也有吗?截图:imgur.com/Vy0aq5N
  • 我已经用新代码更新了我的问题。如您所见,我已经完全按照您上面显示的方式完成了。为什么上帝必须破坏我的 zip 文件?
  • 这真的很奇怪。代码是相同的,应该可以工作。您仍然遇到与最初相同的错误吗?
  • zipOutputStream.SetLevel(0); 在循环中的任何具体原因?
【解决方案2】:

我的 blob 容器是私有的,这就是文件从未下载的原因。

我实际上认为我的容器是公共的,但直到我在 Azure 存储资源管理器中探索了我的容器后,我才发现该容器是私有的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-03
    • 2021-12-31
    • 2020-03-24
    • 2021-08-09
    • 1970-01-01
    • 2018-01-09
    • 1970-01-01
    相关资源
    最近更新 更多