我正在将文件上传到azure存储.
public class AzureBlob : ICloudBlob
{
private string _fileName;
public string FileName
{
get => _fileName;
set
{
_fileName = value;
_cloudBlockBlob = CloudBlobContainer.GetBlockBlobReference(value);
}
}
public CloudBlobContainer CloudBlobContainer { get; set; }
private CloudBlockBlob _cloudBlockBlob;
public async Task UploadChunksFromPathAsync(string path, long fileLength)
{
const int blockSize = 256 * 1024;
var bytesToUpload = fileLength;
long bytesUploaded = 0;
long startPosition = 0;
var blockIds = new List<string>();
var index = 0;
do
{
var bytesToRead = Math.Min(blockSize, bytesToUpload);
var blobContents = new byte[bytesToRead];
using (var fs = new FileStream(path, FileMode.Open))
{
fs.Position = startPosition;
fs.Read(blobContents, 0, (int) bytesToRead);
}
var blockId = Convert.ToBase64String(Encoding.UTF8.GetBytes(index.ToString("d6")));
blockIds.Add(blockId);
await _cloudBlockBlob.PutBlockAsync(blockId, new MemoryStream(blobContents), null);
bytesUploaded += bytesToRead;
bytesToUpload -= bytesToRead;
startPosition += bytesToRead;
index++;
} while (bytesToUpload > 0);
await _cloudBlockBlob.PutBlockListAsync(blockIds);
}
}
这适用于一个文件上传,多个文件上传一个接一个地调用此方法在_cloudBlockBlob.PutBlockListAsync上抛出400错误,天蓝色错误是
The specified blob or block content is invalid.
如果我在_cloudBlockBlob.PutBlockListAsync上删除了await关键字,它可以正常工作.
blockIds的长度都相同.我究竟做错了什么?
编辑
在控制器中调用代码:
[HttpPost]
public async Task<IActionResult> Upload([FromBody] UploadViewModel model)
{
var audioBlob = _cloudStorage.GetBlob(CloudStorageType.Audio, model.AudioName);
await audioBlob.UploadChunksFromPathAsync(model.AudioPath, model.FileLength);
return Ok();
}
存储:
public enum CloudStorageType
{
Audio,
Image,
}
public class AzureStorage : ICloudStorage
{
public IDictionary<CloudStorageType, ICloudBlob> CloudBlobs { get; set; }
public AzureStorage(IConfiguration configuration)
{
var storageAccount = CloudStorageAccount.Parse(configuration["ConnectionStrings:StorageConnectionString"]);
var blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobs = new Dictionary<CloudStorageType, ICloudBlob>();
foreach (CloudStorageType cloudStorageType in Enum.GetValues(typeof(CloudStorageType)))
{
CloudBlobs[cloudStorageType] = new AzureBlob(cloudStorageType.ToString().ToLower(), blobClient);
}
}
public ICloudBlob GetBlob(CloudStorageType cloudStorageType, string fileName)
{
CloudBlobs[cloudStorageType].FileName = fileName;
return CloudBlobs[cloudStorageType];
}
}
Startup.cs
var azureStorage = new AzureStorage(_configuration);
// Add application services.
services.AddSingleton(_configuration);
services.AddSingleton<ICloudStorage>(azureStorage);
解决方法:
编辑:原因实际上是因为下载文件的下半部分blob被下一个文件覆盖了.基本上每次上传都会创建一个新的blob,所以这不会发生.
弄清楚了.第一次下载可以正常工作,但如果之前的下载尚未完成,第二次下载会抛出错误,因为该块blob已经在使用下载其他块.
修复是为每次下载创建一个新的块blob,而不是仅使用一个.
public async Task UploadChunksFromPathAsync(string path, long fileLength)
{
var cloudBlockBlob = CloudBlobContainer.GetBlockBlobReference(FileName);
const int blockSize = 256 * 1024;
var bytesToUpload = fileLength;
long bytesUploaded = 0;
long startPosition = 0;
var blockIds = new List<string>();
var index = 0;
do
{
var bytesToRead = Math.Min(blockSize, bytesToUpload);
var blobContents = new byte[bytesToRead];
using (var fs = new FileStream(path, FileMode.Open))
{
fs.Position = startPosition;
fs.Read(blobContents, 0, (int) bytesToRead);
}
var blockId = Convert.ToBase64String(Encoding.UTF8.GetBytes(index.ToString("d6")));
blockIds.Add(blockId);
await cloudBlockBlob.PutBlockAsync(blockId, new MemoryStream(blobContents), null);
bytesUploaded += bytesToRead;
bytesToUpload -= bytesToRead;
startPosition += bytesToRead;
index++;
} while (bytesToUpload > 0);
await cloudBlockBlob.PutBlockListAsync(blockIds);
}
原文地址:https://codeday.me/bug/20190622/1264631.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。