寻找替代方法来编写 azure 块 blob 的一部分,因为不支持查找
Looking for alternative to writing part of a azure block blob as seeking is not supported
我有一些遗留代码用于 运行 System.IO 文件系统。
问题是现在不支持seeking了,改成在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();
}
}
基本上代码是用来写大文件的,当文件的一部分已经写完了,它可以从停止的地方继续写。
我正在寻找做过类似事情的人的例子,并更改代码以找到最后提交的块并从那里开始编写
我用了下面的方法。
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);
}
}
}
我有一些遗留代码用于 运行 System.IO 文件系统。
问题是现在不支持seeking了,改成在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();
}
}
基本上代码是用来写大文件的,当文件的一部分已经写完了,它可以从停止的地方继续写。
我正在寻找做过类似事情的人的例子,并更改代码以找到最后提交的块并从那里开始编写
我用了下面的方法。
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);
}
}
}