从azure云存储下载大文件的最佳方式

时间:2011-05-13 04:32:13

标签: asp.net-mvc azure download

我有一个运行在azure中的MVC网络应用程序,可以提供存储在云存储中的大型文件,如mp3,pdf等。提供这些文件的最佳方式是什么,因此用户可以在点击链接/按钮时下载它们?

简单的方法就是向他们展示:

<a href="...blob.core.windows.net/container/file.mp3">

但是用户必须右键单击才能下载。

要强制下载,您可以返回File ActionResult:

public ActionResult GetPDF( string filename )
{
    return File( filename, "application/pdf", Server.HtmlEncode( filename ) );
}

这个(我认为)的缺点是webrole必须读入文件并将它们输出到流,这将消耗资源,并可能使许多用户陷入困境。而简单的href链接解决方案基本上不需要工作,因此浏览器直接与云存储进行对话。

我说错了吗?我应该关注webrole上的额外工作吗?

是否有其他方法可以在不增加webrole负担的情况下强制下载文件?

更新:

所以我最终做的是使用Content-Type“binary / octet-stream”上传mp3 - 这似乎强制下载提示。不确定这是不是一个好习惯,但它到目前为止都有效。

3 个答案:

答案 0 :(得分:4)

您的假设是正确的,如果您想使用ActionResult,您需要先将文件下载到Web角色,然后将其流式传输到客户端。如果你想要避免这种情况,特别是大文件并将其留给Azure存储,因为微软必须担心处理请求,如果你获得大量流量,你不必为更多的网络角色付费。 / p>

如果您托管的所有文件都是公开的,这很有效,但如果您想保护文件,则会变得有点棘手(如果您想要这样做,请查看shared access signatures。)

您是否尝试在blob上设置内容类型?根据您将文件上传到blob存储的方式,可能无法设置它们。如果您通过自己的代码上传blob,可以通过CloudBlob.Attributes.Properties.ContentType(来自MSDN

访问

答案 1 :(得分:1)

您可以返回包含文件下载路径的outputFileName,并在前端显示该路径,并显示已在位置[...]下载文件的消息

答案 2 :(得分:0)

我已经开发了一个ActionResult来从存储中获取文件但是我没有将它输出到流并返回一个下载的文件,我可以得到一个帮助,请将此动作代码: public ActionResult GetPDF(string filename) {

    var storageAccountName = this.User.StorageAccountName;
        var storageAccountKey = this.User.StorageAccountKey;
        string connectionString = string.Format(
                    "DefaultEndpointsProtocol=https;AccountName={0};AccountKey={1}",
                     storageAccountName, storageAccountKey);

        //Extraction de votre chaîne de connexion par programme
        CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);

        //Create a CloudFileClient object for credentialed access to File storage.
        CloudFileClient fileClient = storageAccount.CreateCloudFileClient();

        //Get a reference to the file share . create a share folder take the name of CompanyCode
        CloudFileShare share = fileClient.GetShareReference(this.User.CompanyCode);

        share.CreateIfNotExists();
        byte[] fileBytes = null;
        // create if not Exist
        if (share.Exists())
        {
            // string StoragePath = "/Uploads/Locations/" + LocationToAdd.Id.ToString();

            CloudFileDirectory rootDirectory = share.GetRootDirectoryReference();
            CloudFileDirectory topDirectory = rootDirectory.GetDirectoryReference("Uploads");
            topDirectory.CreateIfNotExistsAsync();
            CloudFileDirectory midDirectory = topDirectory.GetDirectoryReference("Locations");
            midDirectory.CreateIfNotExistsAsync();
            CloudFileDirectory sampleDir = midDirectory.GetDirectoryReference(document1.LocationId.ToString());
            sampleDir.CreateIfNotExistsAsync();
            //Get a reference to the file we created previously.
            CloudFile file = sampleDir.GetFileReference(filename);

            if (file.Exists())
            {
                //Write the contents of the file to the console window.
                // string fileresult = file.DownloadTextAsync().Result;
                //  file.DownloadToByteArray(fileBytes, 1, null, null, null);

                string outputFileName = Path.GetTempFileName();
                if (System.IO.File.Exists(outputFileName))
                {
                    System.IO.File.Delete(outputFileName);
                }
                OperationContext context = new OperationContext();
                file.DownloadToFileAsync(outputFileName, FileMode.CreateNew, null, null, context);

                // what should i do after this ........
            }
            }
            }
}