Azure存储Blob下载进度指示器



下载blob时,我需要一个进度指示器。

上传时进度指示器已工作。我正在BlobUploadOptions中使用Progress处理程序。

Blob下载详细信息似乎有进度状态。然而,我不知道如何将其集成以使其工作。

这是我的代码:

IKeyEncryptionKey key;
IKeyEncryptionKeyResolver keyResolver;
// Create the encryption options to be used for upload and download.
ClientSideEncryptionOptions encryptionOptions = new ClientSideEncryptionOptions(ClientSideEncryptionVersion.V2_0)
{
KeyEncryptionKey = key,
KeyResolver = keyResolver,
// string the storage client will use when calling IKeyEncryptionKey.WrapKey()
KeyWrapAlgorithm = "some algorithm name"
};
// Set the encryption options on the client options
BlobClientOptions options = new SpecializedBlobClientOptions() { ClientSideEncryption = encryptionOptions };
// Get your blob client with client-side encryption enabled.
// Client-side encryption options are passed from service to container clients, and container to blob clients.
// Attempting to construct a BlockBlobClient, PageBlobClient, or AppendBlobClient from a BlobContainerClient
// with client-side encryption options present will throw, as this functionality is only supported with BlobClient.
BlobClient blob = new BlobServiceClient(connectionString, options).GetBlobContainerClient("myContainer").GetBlobClient("myBlob");
BlobUploadOptions uploadOptions = new BlobUploadOptions();
uploadOptions.ProgressHandler = new Progress<long>(percent =>
{
progressbar.Maximum = 100;
progressbar.Value = Convert.ToInt32(percent * 100 / file.Length);
});
// Upload the encrypted contents to the blob.
blob.UploadAsync(content: stream, options: uploadOptions, cancellationToken: CancellationToken.None);
// Download and decrypt the encrypted contents from the blob.
MemoryStream outputStream = new MemoryStream();
blob.DownloadTo(outputStream);

当前,DownloadTo方法不支持进度监视器。当浏览源代码时,DownloadTo方法在BlobBaseClient类中定义,而UploadAsync方法在继承自BlobBaseClient类的BlobClient类中定义。所以我认为他们可能会错过基类BlobBaseClient中的这个特性。

但有一个变通方法,代码如下:

class Program
{
static void Main(string[] args)
{
var connectionString = "DefaultEndpointsProtocol=https;AccountName=xx;AccountKey=xxx;EndpointSuffix=core.windows.net";
BlobServiceClient blobServiceClient = new BlobServiceClient(connectionString);
BlobContainerClient blobContainerClient = blobServiceClient.GetBlobContainerClient("xxx");
BlobClient blobClient = blobContainerClient.GetBlobClient("xxx");
var blobToDownload = blobClient.Download().Value;

MemoryStream outputStream = new MemoryStream();
var downloadBuffer = new byte[81920];
int bytesRead;
int totalBytesDownloaded = 0;
while ((bytesRead = blobToDownload.Content.Read(downloadBuffer, 0, downloadBuffer.Length)) != 0)
{
outputStream.Write(downloadBuffer, 0, bytesRead);
totalBytesDownloaded += bytesRead;
Console.WriteLine(GetProgressPercentage(blobToDownload.ContentLength, totalBytesDownloaded));
}
Console.WriteLine("**completed**");
Console.ReadLine();
}
private static double GetProgressPercentage(double totalSize, double currentSize)
{
return (currentSize / totalSize) * 100;
}
}

这是参考文件。

DownloadStreamingAsync支持进度回调,因此这里有一种替代方法。。。

{
...
var blobClient = containerClient.GetBlobClient(fileName);
var targetPath = Path.Combine(Path.GetTempPath(), fileName);
var prop = await blobClient.GetPropertiesAsync();
var length = prop.Value.ContentLength;
var download = await blobClient.DownloadStreamingAsync(new HttpRange(0, length),
new BlobRequestConditions(),
false,
new ProgressTracker(log, length),
CancellationToken.None);
var data = download.Value.Content;
await using (var fileStream = File.Create(targetPath))
{
await data.CopyToAsync(fileStream);
}
}
private class ProgressTracker : IProgress<long>
{
private readonly TextWriter _logWriter;
private readonly long _totalLength;
private double _progress = -100;
public ProgressTracker(TextWriter logWriter, long totalLength)
{
_totalLength = totalLength;
_logWriter = logWriter;
}
public void Report(long value)
{
var progress = ((double)value / _totalLength) * 100;
if (Math.Abs(progress - _progress) > 1)
{
_progress = progress;
_logWriter.WriteLine($"{Math.Round(_progress, 0)}%");
}
}
}

最新更新