web-dev-qa-db-ja.com

AzureBLOBストレージファイルからZipファイルを生成する

WindowsAzureの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して新しいZipファイルを作成できるようにしたい

https://mystorage.blob.core.windows.net/myzippedfiles/allmyFiles.Zip)そしてZipファイルへのパスを返します

AzureBLOBに多数のファイルがあります。したがって、それらをダウンロードして圧縮し、アップロードすることはお勧めできません。

どうすればこれを行うことができますか。これを行うにはサンプルコードが必要です

18
Steve

この問題は、blobストリームを使用してファイルを出力ストリームに直接圧縮することで(部分的に)解決しました。これにより、zipをダウンロードしてから送信する問題が回避され、これが発生する間の遅延が回避されます(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);
        }
28
Richard

BLOBストレージは"just"オブジェクトストアであるため、どこかにダウンロードし(Web /ワーカーロールまたはローカルコンピューターの場合があります)、Zipしてから、Zipファイルを再アップロードする必要があります。私の知る限り、それが唯一の方法です。

3
Gaurav Mantri

使用しているZipライブラリが何であれ、Zipファイルを作成するためにローカルリソース/ローカルファイルが必要になると99%確信しています。

ワーカーロール用の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を使用してすべてのファイルパスをまとめます。

2
Eoin Campbell

それらをダウンロードし、ローカルで圧縮し、アップロードし直すことは避けられないと思います。

圧縮ユーティリティは、ローカルリソースでのみ機能します。 Azure Storage自体には、一部のファイルを単独で圧縮できるという概念/機能がありません。

2
Igorek

Webジョブまたはワーカーロールを使用してそれを行うことができると思います。ユーザーのリクエストを受け取ったら、このリクエストをキューにプッシュしてから、ジョブIDをユーザーに返します。 Webjobまたはworkerロールは、キューからリクエストをフェッチし、これらのファイルをダウンロードしてZipし、ZipファイルをStorageblobにアップロードします。フロントサイドコードは、ジョブIDを使用したajaxロールポーリングを使用して、完了時に実際のダウンロードURLを取得できます。

0
Crazy Crab