寻找替代编写azure块blob的一部分作为搜索不支持

时间:2017-02-06 19:51:58

标签: azure storage

我有一些用于在System.IO文件系统上运行的遗留代码。

问题在于它现在不支持我将其更改为在azure上使用blockBlob。

    var contentLength = Math.Max(0, blob.Properties.Length);
    var request = new HttpRequestMessage { RequestUri = new Uri(source.Metadata.MediaSrc) };
    request.Headers.Range = new RangeHeaderValue();
    request.Headers.Range.Ranges.Add(new RangeItemHeaderValue(contentLength, null));

    var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);

    response.EnsureSuccessStatusCode();

    using (var stream = await blob.OpenWriteAsync(cancellationToken))
    {
        if (contentLength > 0)
        {
            stream.Seek(contentLength, SeekOrigin.Begin);
        }
        try
        {
            using (var responeStream = await response.Content.ReadAsStreamAsync())
            {
                await responeStream.CopyToAsync(stream, 81920, cancellationToken);
            }
        }                                       
        finally
        {
            await stream.FlushAsync();
            stream.Dispose();
        }
    }

基本上,代码用于写入大文件,当文件的一部分已经写入时,它可以继续从停止的位置写入。

我正在寻找那些做过类似事情并更改代码以找到最后提交的块并从那里开始写的人的例子

1 个答案:

答案 0 :(得分:0)

我用以下方法做到了。

var blocksize = 0L;
var list = new List<string>();
if (contentLength > 0)
{
    var blocks = await blob.DownloadBlockListAsync(BlockListingFilter.Committed, null, null, null);
    contentLength = blocks.Aggregate(0L, (seed, item) => seed + item.Length);
    blocksize = blocks.First().Length;
    list.AddRange(blocks.Select(k => k.Name));
}

_logger.LogTrace("Item {id} with contentLenght {contentLenght}:{expectedContentLength} is starting to download", a.Value.Source.Id, contentLength, expectedContentLength);


var request = new HttpRequestMessage { RequestUri = new Uri(source.Metadata.MediaSrc) };
request.Headers.Range = new RangeHeaderValue();// (info.Length, Math.Min(length, info.Length+ BlockDownSize));
request.Headers.Range.Ranges.Add(new RangeItemHeaderValue(contentLength, null));

var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);

response.EnsureSuccessStatusCode();

    private static async Task DownloadMissingBlocksAsync(CloudBlockBlob blob, long totalMissing, long blocksize, List<string> list, HttpResponseMessage response, CancellationToken cancellationToken)
    {
        var buffer = new byte[blocksize];
        // var read = -1;
        var blockIdPrefix = Guid.NewGuid().ToString("N") + "-";

        using (var responeStream = await response.Content.ReadAsStreamAsync())
        {
            try
            {


                while (totalMissing > 0)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    var missingRead = buffer.Length;

                    while (Math.Min((int)totalMissing, (int)missingRead) > 0)
                    {
                        var read = await responeStream.ReadAsync(buffer, buffer.Length - missingRead, Math.Min((int)totalMissing, (int)missingRead));
                        missingRead -= read;
                        totalMissing -= read;
                    }

                    string blockIdSuffix = list.Count.ToString("D6", CultureInfo.InvariantCulture);
                    byte[] blockIdInBytes = Encoding.UTF8.GetBytes(blockIdPrefix + blockIdSuffix);
                    var blockid = Convert.ToBase64String(blockIdInBytes);

                    await blob.PutBlockAsync(blockid, new MemoryStream(buffer, 0, buffer.Length - missingRead), null);
                    list.Add(blockid);
                }
            } 
            finally
            {
                await blob.PutBlockListAsync(list);
            }

        }


    }