1

我遇到了从 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 在下载后给出了正确的长度,流通常会说一些更低的内容。我已经尝试通过范围下载,但无济于事

4

1 回答 1

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;
        }
    }
于 2013-05-09T22:49:37.563 回答