1

通过一个网页,我想让用户下载存储在 Azure 云存储上的(非常大的)文件。我使用 GetSharedAccessSignature 来允许用户下载它(注意:Container 是受保护的,不能公开阅读)。我使用以下代码:

// 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

从代码看来,您实际上是在让浏览器进行下载。在这种情况下,我相信选择是让共享访问签名有效期更长。

另一个想法是让您的代码读取 blob 的块,然后传输这些块。这样,如果需要,您可以创建一个新的 SAS URI,并在 SAS URI 超时已过期且 blob 尚未完全下载时使用它。

看看下面的示例代码。基本上在这个示例中,我有一个 200 MB 的 blob。在循环中,我的代码读取 1 MB 的 blob 块并将该块向下发送。

        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 回答