从azure blob存储文件生成Zip文件

时间:2013-09-17 14:17:56

标签: c# visual-studio-2012 azure azure-storage-blobs

我的windows azure blob存储中存储了一些文件。我想获取这些文件并创建一个zip文件并存储到一个新文件夹。然后返回zip文件的路径。 设置zip文件位置的权限,以便我的用户可以通过单击链接

将zip文件下载到本地计算机
 https://mystorage.blob.core.windows.net/myfiles/2b5f8ea6-3dc2-4b77-abfe-4da832e02556/AppList/isjirleq/mydocs1.doc
 https://mystorage.blob.core.windows.net/myfiles/2b5f8ea6-3dc2-4b77-abfe-4da832e02556/tempo/xyz/mymusic.mp3
 https://mystorage.blob.core.windows.net/myfiles/2b5f8ea6-3dc2-4b77-abfe-4da832e02556/general/video/myVideo.wmv
 https://mystorage.blob.core.windows.net/myfiles/2b5f8ea6-3dc2-4b77-abfe-4da832e02556/photo/photo1.png

我希望能够循环使用这些文件并将它们拼接在一起以创建新的zip文件

https://mystorage.blob.core.windows.net/myzippedfiles/allmyFiles.zip)并返回zip文件的路径

我的azure blob中有大量文件。所以下载它们并压缩它们并上传并不是一个好主意。

我该怎么做。我需要一些示例代码才能做到这一点

7 个答案:

答案 0 :(得分:27)

我们已经通过使用blob流将文件直接压缩到输出流来解决了这个问题(部分)。这避免了下载压缩然后发送的问题,并避免了发生这种情况时的延迟(我们使用ICSharpZipLib,reference)。但它仍然意味着通过Web服务器路由流:

  public void ZipFilesToResponse(HttpResponseBase response, IEnumerable<Asset> files, string zipFileName)
    {
        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);
            response.ContentType = "application/octet-stream";

            foreach (var file in files)
            {
                var entry = new ZipEntry(file.FilenameSlug())
                {
                    DateTime = DateTime.Now,
                    Size = file.Filesize
                };
                zipOutputStream.PutNextEntry(entry);
                storageService.ReadToStream(file, zipOutputStream);
                response.Flush();
                if (!response.IsClientConnected)
                {
                   break;
                }
            }
            zipOutputStream.Finish();
            zipOutputStream.Close();
        }
        response.End();
    }

存储服务只是这样做:

public void ReadToStream(IFileIdentifier file, Stream stream, StorageType storageType = StorageType.Stored, ITenant overrideTenant = null)
    {
        var reference = GetBlobReference(file, storageType, overrideTenant);
        reference.DownloadToStream(stream);
    }
private CloudBlockBlob GetBlobReference(IFileIdentifier file, StorageType storageType = StorageType.Stored, ITenant overrideTenant = null)
        {
            var filepath = GetFilePath(file, storageType);
            var container = GetTenantContainer(overrideTenant);
            return container.GetBlockBlobReference(filepath);
        }

答案 1 :(得分:3)

由于blob存储“只是”一个对象存储,你需要将它们下载到某个地方(它可能是一个web / worker角色或你的本地计算机),压缩它们然后重新上传zip文件。就我所知,这是唯一的方法。

答案 2 :(得分:2)

我认为你不能避免下载它们,在本地压缩它们并将它们上传回来。

压缩实用程序仅适用于本地资源。 Azure存储本身没有能够自行压缩某些文件的概念/能力

答案 3 :(得分:2)

我99%确定您使用的任何zip库都需要本地资源/本地文件才能创建zip文件。

查看Azure Local Storage for Worker角色。

http://vkreynin.wordpress.com/2010/01/10/learning-azure-local-storage-with-me/

您可以在工作人员角色中指定本地存储量,以便保存正在处理的内容。

e.g。

//在配置中创建一个本地存储部分。

<WebRole name="...">
 <LocalResources>
   <LocalStorage name="myLocalStorage" sizeInMB="50"/>
 </LocalResources>
</WebRole>

//然后将文件保存到本地存储

CloudBlobContainer container = blobClient.GetContainerReference("myfiles");
CloudBlob blob = container.GetBlobReference("2b5f8ea6-3dc2-4b77-abfe-4da832e02556/AppList/isjirleq/mydocs1.doc");

LocalResource myStorage = RoleEnvironment.GetLocalResource("myLocalStorage");
string filePath = Path.Combine(myStorage.RootPath, "mydocs1.doc");
blob.DownloadToFile(filePath);

在LocalStorage中保存所有文件后,使用ZipLibrary将所有文件路径捆绑在一起

答案 4 :(得分:0)

我认为你可以使用webjob或worker角色来完成它。当您收到用户的请求时,将此请求推送到队列中,然后将作业ID返回给用户。 Webjob或辅助角色从队列中获取请求,并下载这些文件并压缩它们,然后将zip文件上载回存储blob。前端代码可以使用带有作业ID的ajax roll polling来获取真正的下载URL。

答案 5 :(得分:0)

我已经使用网站上的JSZip从Azure Blob存储下载多个文件了

var urls = [
"images/20170420_145140.jpg",
"images/20170503_142841.jpg",
"images/20170503_084035.jpg"];


download() {

    urls.forEach(function (url) {
        JSZipUtils.getBinaryContent(url, function (err, data) {
            if (err) {
                throw err; // or handle the error
            }
            try {
                zip.file(count + ".jpg", data, { binary: true });
                count++;
                if (count == urls.length) {
                    zip.generateAsync({ type: "blob" }).then(function (content) {
                        FileSaver.saveAs(content, zipFilename);
                    });
                }
            } catch (e) {
                console.log("errorrr...k", e)
            }
        });
    });
}

答案 6 :(得分:-1)

不要认为azure为压缩提供任何开箱即用的功能。如果你需要避免周转时间,那么使用后台工作者角色是一个好主意,它将从某个队列中挑选你的文件.zip他们上传它们并存储url for你在某个地方就像sql db。我在与db进行通信时做了类似的事情,所以你可以放心它会很快工作而不会让用户意识到它实际上并没有发生在前端。