使用 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 校验和吗?

md5验证文件上传,确保信息传输完整一致

上传文件需要MD5值,这个是啥?

如何禁用分段上传,以便同步匹配 s3cmd 中本地和远程文件的 md5sum

nginx安装upload和MD5,echo模块

nodejs怎样获取一个上传文件的MD5码?