1

Web ページを介して、ユーザーが Azure クラウド ストレージに保存されている (非常に大きな) ファイルをダウンロードできるようにしたいと考えています。GetSharedAccessSignature を使用して、ユーザーがダウンロードできるようにします (注: コンテナーは保護されており、公開されていません)。次のコードを使用します。

// get the file blob
// CloudBlockBlob blob set previously and check (it exists)

        string sas = blob.GetSharedAccessSignature(
            new SharedAccessPolicy() { 
                Permissions = SharedAccessPermissions.Read,
                SharedAccessStartTime = DateTime.Now.AddMinutes(-5),
                SharedAccessExpiryTime = DateTime.Now.AddMinutes(54) 
            });

        Response.Redirect(blob.Attributes.Uri.AbsoluteUri + sas);

これは、ダウンロードに 1 時間以上かかる場合を除いて機能します (前述したように、非常に大きなファイルがあまり良好でないインターネット接続でダウンロードされます...)。ダウンロードに時間がかかる場合、タイムアウトが発生し、共有アクセスの有効期限が過ぎるとダウンロードが停止します。

どうすればこれを解決できますか?

敬具、 ロビー・デ・サッター

4

1 に答える 1

0

コードから、実際にはブラウザにダウンロードを任せているようです。そのシナリオでは、Shared Access Signature の有効期間を延長することが選択肢になると思います。

さらに別のアイデアは、コードで BLOB のチャンクを読み取ってから、それらのチャンクを送信することです。そうすれば、必要に応じて新しい SAS URI を作成し、SAS URI タイムアウトが期限切れになり、BLOB が完全にダウンロードされていない場合にそれを使用できます。

以下のサンプルコードを見てください。基本的に、このサンプルでは、​​200 MB のブロブがあります。ループでは、私のコードはブロブの 1 MB チャンクを読み取り、そのチャンクを送信します。

        protected void ButtonDownload_Click(object sender, EventArgs e)
    {
        var blobUri = "http://127.0.0.1:10000/devstoreaccount1/abc/test2.vhd?sr=b&st=2012-08-17T10%3A29%3A46Z&se=2012-08-17T11%3A29%3A46Z&sp=r&sig=dn7cnFhP1xAPIq0gH6klc4nifqgk7jfOgb0hV5Koi4g%3D";
        CloudBlockBlob blockBlob = new CloudBlockBlob(blobUri);
        var blobSize = 200 * 1024 * 1024;
        int blockSize = 1024 * 1024;
        Response.Clear();
        Response.ContentType = "APPLICATION/OCTET-STREAM";
        System.String disHeader = "Attachment; Filename=\"" + blockBlob.Name + "\"";
        Response.AppendHeader("Content-Disposition", disHeader);
        for (long offset = 0; offset < blobSize; offset += blockSize)
        {
            using (var blobStream = blockBlob.OpenRead())
            {
                if ((offset + blockSize) > blobSize)
                    blockSize = (int)(blobSize - offset);
                byte[] buffer = new byte[blockSize];
                blobStream.Read(buffer, 0, buffer.Length);
                Response.BinaryWrite(buffer);
                Response.Flush();
            }
        }
        Response.End();
    }

お役に立てれば。

于 2012-08-17T10:54:13.707 に答える