尝试下载较大的Blob文件

时间:2019-10-08 12:28:25

标签: c# azure download blob azure-storage-blobs

我需要从存储帐户下载大型备份文件。 我使用SAS进行尝试,并生成链接,当我使用该链接并输入该链接时 直接将其下载到浏览器中会下载文件,但是当我尝试通过我的代码下载文件时,它将给我空文件或根本不下载文件。注释掉的行是我已经尝试过的,最后一个是Redirect(blobSasuri);

public async Task DownloadBlobItemAsync([FromQuery] string userId, [FromRoute] string fileName, [FromBody] PathObject path, [FromRoute] int filestorageConnectionId)
{
    var fileStorageConnection = await _customerProvider.GetFileStorageConnection(filestorageConnectionId);
    var customer = await _customerProvider.GetCustomer(fileStorageConnection.CustomerId);

    CloudBlockBlob blob = _fileStorage.DownloadBlobFile(fileStorageConnection.Id, userId, customer.Id, fileName, path.Path);

    var sas = blob.GetSharedAccessSignature(new SharedAccessBlobPolicy()
    {
        SharedAccessStartTime = DateTime.UtcNow.AddHours(-5),
        SharedAccessExpiryTime = DateTime.UtcNow.AddHours(5),
        Permissions = SharedAccessBlobPermissions.Read
    });

    string blobSasUri = (string.Format(CultureInfo.InvariantCulture, "{0}{1}", blob.Uri, sas));

    // CloudBlockBlob blobNew = new CloudBlockBlob(new Uri(blobSasUri));

    // var pathNew = Directory.GetCurrentDirectory();
    // blobNew.DownloadToFileAsync(pathNew, FileMode.Create);

    //await blob.DownloadToFileAsync(blobSasUri, FileMode.Create);

    Redirect(blobSasUri);

    //using (var client = new WebClient())
    //{
    //    client.DownloadFile(blobSasUri, fileName);
    //}
}

2 个答案:

答案 0 :(得分:0)

我不知道您用什么方法下载Blob,我用blobSas.DownloadToStream()测试了一下,它对我有用。所以也许您可以尝试使用我的代码。

 static void Main(string[] args)
    {
        string storageConnectionString = "connectin string";

        // Check whether the connection string can be parsed.
        CloudStorageAccount storageAccount;

        CloudStorageAccount.TryParse(storageConnectionString, out storageAccount);

        var containerName = "test";
        var blobName = "testfile.zip";
        string saveFileName = @"E:\testfilefolder\myfile1.zip";

        var blobContainer = storageAccount.CreateCloudBlobClient().GetContainerReference(containerName);
        var blob = blobContainer.GetBlockBlobReference(blobName);
        var sas =blob.GetSharedAccessSignature(new SharedAccessBlobPolicy()
        {
            SharedAccessStartTime = DateTime.UtcNow.AddHours(-5),
            SharedAccessExpiryTime = DateTime.UtcNow.AddHours(5),
            Permissions = SharedAccessBlobPermissions.Read
        });
        string blobSasUri = (string.Format(CultureInfo.InvariantCulture, "{0}{1}", blob.Uri, sas));

        //Download Blob through SAS url
        CloudBlockBlob blobSas = new CloudBlockBlob(new Uri(blobSasUri));

        long startPosition = 0;
        using (MemoryStream ms = new MemoryStream())
        {
            blobSas.DownloadToStream(ms);
            byte[] data = new byte[ms.Length];
            ms.Position = 0;
            ms.Read(data, 0, data.Length);

            using (FileStream fs = new FileStream(saveFileName, FileMode.OpenOrCreate))
            {
                fs.Position = startPosition;
                fs.Write(data, 0, data.Length);
            }
        }
    }

除了使用sas url下载大的blob之外,另一种选择是以大块形式提供文件。这是代码。

        int segmentSize = 1 * 1024 * 1024;//1 MB chunk

        var blobContainer = storageAccount.CreateCloudBlobClient().GetContainerReference(containerName);
        var blob = blobContainer.GetBlockBlobReference(blobName);
        blob.FetchAttributes();
        var blobLengthRemaining = blob.Properties.Length;
        long startPosition = 0;
        string saveFileName = @"E:\testfilefolder\myfile.zip";
        do
        {
            long blockSize = Math.Min(segmentSize, blobLengthRemaining);
            byte[] blobContents = new byte[blockSize];
            using (MemoryStream ms = new MemoryStream())
            {
                blob.DownloadRangeToStream(ms, startPosition, blockSize);
                ms.Position = 0;
                ms.Read(blobContents, 0, blobContents.Length);
                using (FileStream fs = new FileStream(saveFileName, FileMode.OpenOrCreate))
                {
                    fs.Position = startPosition;
                    fs.Write(blobContents, 0, blobContents.Length);
                }
            }
            startPosition += blockSize;
            blobLengthRemaining -= blockSize;
        }
        while (blobLengthRemaining > 0);

希望这可以为您提供帮助,如果仍然有其他问题,请随时告诉我。

答案 1 :(得分:0)

这不适用于我和大于5 GB的大文件。我所做的是我返回了文件的路径,并在其上添加了SAS,并将其返回到前端。因此,现在在前端,我已经与sas链接,并且可以通过浏览器直接将其下载到那里。