使用 WriteRange 和 MD5 上传 Azure 文件存储是 KO
Posted
技术标签:
【中文标题】使用 WriteRange 和 MD5 上传 Azure 文件存储是 KO【英文标题】:Azure File Storage upload with WriteRange and MD5 is KO 【发布时间】:2020-11-26 10:44:46 【问题描述】:我正在尝试使用 C# REST API 库在 azure 存储中上传文件。我希望能够上传具有上传百分比的文件,所以我查看了文档并尝试使用 WriteRange 方法来实现这一点。
它正在工作,但我无法存储文件的 MD5(并在以后检索它)。
这是我的复制案例:
static void Main(string[] args)
var storageAccount = CloudStorageAccount.Parse(connectionString);
var fileClient = storageAccount.CreateCloudFileClient();
var share = fileClient.GetShareReference(shareReference);
var rootDir = share.GetRootDirectoryReference();
var firstFileCloudName = "test/file1.txt";
var firstFilePath = "c:\\test\\file1.txt";
var secondFileCloudName = "test/file2.txt";
var secondFilePath = "c:\\test\\file2.txt";
// upload first file
var firstFile = rootDir.GetFileReference(firstFileCloudName);
firstFile.UploadFromFile(firstFilePath, options: new FileRequestOptions StoreFileContentMD5 = true );
// check md5 of first file
var checkFirstFile = rootDir.GetFileReference(firstFileCloudName);
if (checkFirstFile.Exists() && checkFirstFile.Properties.ContentMD5 == Convert.ToBase64String(MD5.Create().ComputeHash(File.ReadAllBytes(firstFilePath))))
Console.WriteLine("First file OK"); // OK
// upload second file with chunks
var secondFile = rootDir.GetFileReference(secondFileCloudName);
Upload(secondFile, secondFilePath);
// check md5 of second file
var checksecondFile = rootDir.GetFileReference(secondFileCloudName);
if (checksecondFile.Exists() && checksecondFile.Properties.ContentMD5 == Convert.ToBase64String(MD5.Create().ComputeHash(File.ReadAllBytes(secondFilePath))))
Console.WriteLine("Second file OK"); // KO !!!
// but the file is correctly uploaded because downloaded md5 is OK
var downloadedFile = rootDir.GetFileReference(secondFileCloudName);
var memoryStream = new MemoryStream();
downloadedFile.DownloadToStream(memoryStream);
if (Convert.ToBase64String(MD5.Create().ComputeHash(memoryStream.ToArray())) == Convert.ToBase64String(MD5.Create().ComputeHash(File.ReadAllBytes(secondFilePath))))
Console.WriteLine("Second file downloaded OK"); // KO !!!
private static void Upload(CloudFile currentFile, string file)
var options = new FileRequestOptions StoreFileContentMD5 = true ;
long bytesToUpload = new FileInfo(file).Length;
long fileSize = bytesToUpload;
currentFile.Create(fileSize);
var blockSize = 256 * 1024;
currentFile.StreamWriteSizeInBytes = blockSize;
int index = 1;
long startPosition = 0;
long bytesUploaded = 0;
var allBytes = File.ReadAllBytes(file);
var ms = new MemoryStream(allBytes);
do
var bytesToRead = Math.Min(blockSize, bytesToUpload);
var blobContents = new byte[bytesToRead];
ms.Position = startPosition;
ms.Read(blobContents, 0, (int)bytesToRead);
var md5 = Convert.ToBase64String(MD5.Create().ComputeHash(new MemoryStream(blobContents)));
currentFile.WriteRange(new MemoryStream(blobContents), startPosition, md5, options: options);
bytesUploaded += bytesToRead;
bytesToUpload -= bytesToRead;
startPosition += bytesToRead;
index++;
double percentComplete = (double)bytesUploaded / fileSize;
Console.WriteLine("Percent complete = " + percentComplete.ToString("P"));
while (bytesToUpload > 0);
currentFile.SetProperties(options: options);
一些解释:
第一种情况,使用 UploadFromFile 上传:它正在工作,我可以存储和读取 MD5。 (我可以在 azure 门户中看到 MD5 正确存储在属性中)
第二种情况,自定义上传,ContentMD5 为空。 (我可以在 Azure 门户中看到 MD5 未存储在属性中)
但是当我下载第二个文件并计算md5时,文件是正确的,所以上传是可以的。
如何通过第二次上传将 MD5 存储在 azure 文件中? (或用百分比改变上传方式)
【问题讨论】:
交叉链接 Azure SDK GitHub 存储库上的相关问题 - github.com/Azure/azure-sdk-for-net/issues/18774 【参考方案1】:其实在上传的最后,我可以手动设置MD5;我以为它只是得到:
currentFile.Properties.ContentMD5 = md5;
currentFile.SetProperties();
【讨论】:
以上是关于使用 WriteRange 和 MD5 上传 Azure 文件存储是 KO的主要内容,如果未能解决你的问题,请参考以下文章
azure 会为容器中上传的所有 blob 计算 md5 校验和吗?