我遇到从Azure存储下载不完整blob的问题。存储的文件是图像。几乎每个下载的文件都会在底部丢失几行。我检查了blob并正确上传了它们。 我正在使用以下代码从Azure服务下载blob:
private async Task Download(CloudBlobClient client)
{
try
{
_media = await _directory.CreateFileAsync(ResourceName, CreationCollisionOption.FailIfExists);
}
catch (Exception)
{
return;
}
using (var stream = await _media.OpenAsync(FileAccessMode.ReadWrite))
{
var blob = await GetBlob(client);
await blob.DownloadToStreamAsync(stream);
_category.NotifyAzureProgress();
await stream.FlushAsync();
}
}
方法GetBlob()如下所示:
private async Task<CloudBlockBlob> GetBlob(CloudBlobClient client)
{
CloudBlobContainer container = client.GetContainerReference(ContainerName);
await container.CreateIfNotExistsAsync();
var blob = container.GetBlockBlobReference(ResourceName);
return blob;
}
上传代码:
private async Task UploadAsync(CloudBlobClient client)
{
_media = await _directory.GetFileAsync(ResourceName);
using (var stream = await _media.OpenAsync(FileAccessMode.Read))
{
var blob = await GetBlob(client);
await blob.UploadFromStreamAsync(stream);
_category.NotifyAzureProgress();
}
}
感谢您的帮助!
编辑:我意识到我错过了一个细节 - 下载的图像具有正确的尺寸,但是底部的几条线是黑色的 - 它与源图像的像素不同。我检查了MD5哈希值,当它们匹配时,当我通过外部应用程序下载图像时,当我使用上面的代码下载它们时它们不匹配。
Edit2:在检查了CloudBlob和输出流的属性之后,我注意到,即使blob在下载后给出了正确的长度,但流通常会说低一些。我已尝试下载整个范围,但无济于事
答案 0 :(得分:0)
好的,所以我设法通过部分使用WinRT Azure库和标准的.NET HttpClient来下载图像。
我使用Azure Lib建立初始连接,然后只获取Blob引用,因为BlockBlobReference有一个创建共享访问签名的方法(我真的不想尝试自己构建它)。然后我创建了HttpClient,使用SAS创建了一个下载URL,并向URL发出了一个GET请求,最终工作并完整地下载了所有图像。
我认为官方库中可能存在一些奇怪的错误,因为使用我的下载方法而不是他们的解决了所有问题。
代码示例:
internal async Task Download(CloudBlobClient client)
{
try
{
_media = await _directory.CreateFileAsync(ResourceName, CreationCollisionOption.FailIfExists);
}
catch (Exception)
{
return;
}
try
{
var blob = await GetBlob(client);
HttpClient httpClient = new HttpClient();
var date = DateTime.UtcNow;
var policy = new SharedAccessBlobPolicy();
policy.Permissions = SharedAccessBlobPermissions.Read;
policy.SharedAccessStartTime = new DateTimeOffset(date);
policy.SharedAccessExpiryTime = new DateTimeOffset(date.AddDays(1));
var signature = blob.GetSharedAccessSignature(policy);
var uriString = string.Format("{0}{1}", blob.Uri.ToString(), signature);
var data = await httpClient.GetByteArrayAsync(uriString);
var buf = new Windows.Storage.Streams.Buffer((uint)data.Length);
await FileIO.WriteBytesAsync(_media, data);
_category.NotifyAzureProgress();
}
catch (Exception e)
{
_media.DeleteAsync();
throw e;
}
}