简体   繁体   English

Azure下载,带有大文件的GetSharedAccessSignature

[英]Azure download with GetSharedAccessSignature of large file

Through a webpage, I want to allow users to download (very large) file stored on Azure Cloud storage. 我希望通过网页允许用户下载(很大)存储在Azure云存储上的文件。 I use the GetSharedAccessSignature to allow users to download it (note: the Container is protected and not publicly readable). 我使用GetSharedAccessSignature来允许用户下载它(请注意:该容器受保护并且不能公开读取)。 I use the following code: 我使用以下代码:

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

This works EXCEPT when the download takes more than 1 hour (as I said, very large files being downloaded over not so good internet connection...). 当下载时间超过1小时(如我所说,非常大的文件正在通过不太好的Internet连接下载)时,此功能除外。 If the download takes longer, a time-out occurs and the download stops as the Shared Access Expired Time has passed. 如果下载花费更长的时间,则会发生超时,并且随着共享访问过期时间的过去,下载将停止。

How can I solve this? 我该如何解决?

Kind regards, Robbie De Sutter 亲切的问候,罗比·德·萨特

From the code, it seems that you're actually letting the browser do the download. 从代码来看,您似乎实际上是在让浏览器进行下载。 In that scenario, I believe the option is to have shared access signatures valid for longer duration. 在那种情况下,我认为选择是使共享访问签名的有效期更长。

Yet another idea is to have your code read the chunks of the blob and then transmit those chunks. 还有一个想法是让您的代码读取Blob的块,然后传输这些块。 That way if there's a need you could create a new SAS URI and use that if the SAS URI timeout has expired and the blob has not downloaded completely. 这样,如果需要,您可以创建一个新的SAS URI,并在SAS URI超时到期且blob尚未完全下载时使用。

Take a look at sample code below. 看下面的示例代码。 Basically in this sample, I have a 200 MB blob. 基本上在此示例中,我有一个200 MB的blob。 In loop, my code reads 1 MB chunk of the blob and sends that chunk down. 在循环中,我的代码读取了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();
    }

Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM