首页 > 解决方案 > 尝试下载大型 blob 文件

问题描述

我需要从我的存储帐户下载大型备份文件。我尝试使用 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);
    //}
}

标签: c#azuredownloadblobazure-blob-storage

解决方案


我不知道你用什么方法下载 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);

希望这可以帮助你,如果你还有其他问题,请随时让我知道。


推荐阅读