大文件上传到Azure文件存储失败

问题描述

尝试上传大于4MB的文件会导致RequestBodyTooLarge异常,并显示以下消息:

The request body is too large and exceeds the maximum permissible limit.

尽管此限制在REST API参考(https://docs.microsoft.com/en-us/rest/api/storageservices/put-range中有所记录),但未在SDK Upload *方法https://docs.microsoft.com/en-us/dotnet/api/azure.storage.files.shares.sharefileclient.uploadasync?view=azure-dotnet)中得到记录。也没有解决此问题的示例。

那么如何上传文件

解决方法

经过反复尝试,我能够创建以下方法来解决文件上传限制。在_dirClient下面的代码中,一个已经初始化的ShareDirectoryClient设置为我要上传到的文件夹。

如果传入的流大于4MB,则代码将从中读取4MB的块并将其上传直到完成。 HttpRange是将字节添加到已经上传到Azure的文件中的位置。索引必须增加以指向Azure文件的末尾,因此将附加新的字节。

public async Task WriteFileAsync(string filename,Stream stream) {

    //  Azure allows for 4MB max uploads  (4 x 1024 x 1024 = 4194304)
    const int uploadLimit = 4194304;

    stream.Seek(0,SeekOrigin.Begin);   // ensure stream is at the beginning
    var fileClient = await _dirClient.CreateFileAsync(filename,stream.Length);

    // If stream is below the limit upload directly
    if (stream.Length <= uploadLimit) {
        await fileClient.Value.UploadRangeAsync(new HttpRange(0,stream.Length),stream);
        return;
    }

    int bytesRead;
    long index = 0;
    byte[] buffer = new byte[uploadLimit];

    // Stream is larger than the limit so we need to upload in chunks
    while ((bytesRead = stream.Read(buffer,buffer.Length)) > 0) {
        // Create a memory stream for the buffer to upload
        using MemoryStream ms = new MemoryStream(buffer,bytesRead);
        await fileClient.Value.UploadRangeAsync(new HttpRange(index,ms.Length),ms);
        index += ms.Length; // increment the index to the account for bytes already written
    }
}
,

如果您要将较大的文件上传到文件共享或Blob存储中,则有Azure Storage Data Movement Library

它为上传,下载较大的文件提供高性能。请考虑将此库用于较大的文件。