从 Azure Blob 存储文件生成 Zip 文件
本文关键字:Zip 文件 存储文件 Azure Blob | 更新日期: 2023-09-27 18:31:49
我有一些文件存储在我的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 中有大量文件。因此,下载,压缩和上传它们不是一个好主意。
我该怎么做?我需要一些示例代码来执行此操作
我们已经通过使用 blob 流将文件直接压缩到输出流(部分)解决了这个问题。这避免了下载压缩然后发送的问题,并避免了发生这种情况时的延迟(我们使用ICSharpZipLib,参考)。但这仍然意味着通过 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);
}
由于 blob 存储"只是"一个对象存储,因此需要将它们下载到某个位置(可以是 Web/辅助角色或本地计算机),压缩它们,然后重新上传 zip 文件。据我所知,这是唯一的方法。
我认为您无法避免下载它们,在本地压缩它们并将它们上传回去。
压缩实用程序仅适用于本地资源。 Azure 存储本身没有能够自行压缩某些文件的概念/能力
我 99% 确定您使用的任何 zip 库都需要本地资源/本地文件才能创建 zip 文件。
请查看辅助角色的 Azure 本地存储。
http://vkreynin.wordpress.com/2010/01/10/learning-azure-local-storage-with-me/
你将能够在辅助角色中指定本地存储量,以便保存进程中可访问的内容。
例如
在配置中创建本地存储部分。
<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 将所有文件路径捆绑在一起
我认为您可以使用 webjob 或 worker 角色来做到这一点。收到用户请求时,将此请求推送到队列中,然后将作业 ID 返回给用户。Web 作业或辅助角色从队列中提取请求,下载这些文件并压缩它们,然后将 zip 文件上传回存储 Blob。前端代码可以使用带有作业 ID 的 ajax 滚动轮询,以便在完成后获取真正的下载 URL。
我已经完成了这个 使用JSZip从网站下载多个文件
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)
}
});
});
}
不要认为 Azure 提供任何开箱即用的压缩功能。使用后台工作线程角色是一个好主意,它将从某个队列中挑选您的文件.zip他们会上传它们并将 url 存储在像 sql db 这样的地方。我在与 db 通信时也做了类似的事情,因此您可以放心,它会非常快速地工作,而不会让用户意识到它实际上并没有在前端发生。