загрузить большие файлы (> 1 ГБ) в хранилище BLOB-объектов Azure через веб-API - PullRequest
0 голосов
/ 06 ноября 2019

у нас есть приложение (ядро .Net), которое размещено в службе приложений Azure, и мы пытаемся загрузить большие файлы в BLOB-объект Azure через веб-API, используя данные формы из пользовательского интерфейса. Мы изменили длину запроса и время ожидания запроса API, но все еще сталкиваемся с ошибками истечения времени соединения, даже при загрузке файлов размером 200 МБ

ниже приведен пример кода, который я использую

[HttpPost]
[Route("upload")]
[Consumes("multipart/form-data")]
[RequestFormLimits(MultipartBodyLengthLimit = 2147483648)]
public async Task<IHttpActionResult> Upload([FromForm] FileRequestObject fileRequestObject)
{
    var url = "upload_url_to_blob_storage";
    var file = fileRequestObject.Files[0];

    var blob = new CloudBlockBlob(new Uri(url));
    blob.Properties.ContentType = file.ContentType;

    await blob.UploadFromStreamAsync(file.InputStream);

    //some other operations based on file upload
    return Ok();
}


public class FileRequestObject
{
    public List<IFormFile> Files { get; set; }
    public string JSON { get; set; }
    public string BlobUrls { get; set; }

}

1 Ответ

0 голосов
/ 07 ноября 2019

Согласно вашему коду, вы хотите выгрузить большой файл в хранилище BLOB-объектов Azure как blockblob. Обратите внимание, что у него есть ограничение. Подробнее см. В документе

. Максимальный размер блочного блоба, созданного с помощью Put Blob, составляет 256 МБ для версии 2016-05-31 и новее, а также 64МБ для более старых версий. Если размер вашего большого двоичного объекта превышает 256 МБ для версии 2016-05-31 и более поздних версий или 64 МБ для более старых версий, необходимо загрузить его в виде набора блоков

Так что если вы хотите использовать большие файлычтобы лазировать блоб, используйте следующие шаги:

1. Прочитайте весь файл в байтах и ​​разделите файл на меньшие части в вашем коде.

  • Возможно 8 МБ для каждой части.

2. Загрузите каждую часть с помощью Put Block API.

  • В каждом запросе он содержит blockid.

3. Составьте блоб с помощью Put Block List API.

  • В этом запросе вы должны поместить все блоки в теле в упорядоченном виде.

Например:

[HttpPost]
        [Consumes("multipart/form-data")]
        [RequestFormLimits(MultipartBodyLengthLimit = 2147483648)]
        public async Task<ActionResult> PostAsync([FromForm]FileRequestObject fileRequestObject)
        {



            string storageAccountConnectionString = "DefaultEndpointsProtocol=https;AccountName=blobstorage0516;AccountKey=UVOOBCxQpr5BVueU+scUeVG/61CZbZmj9ymouAR9609WbqJhhma2N+WL/hvaoNs4p4DJobmT0F0KAs0hdtPcqA==;EndpointSuffix=core.windows.net";
            CloudStorageAccount StorageAccount = CloudStorageAccount.Parse(storageAccountConnectionString);
            CloudBlobClient BlobClient = StorageAccount.CreateCloudBlobClient();
            CloudBlobContainer Container = BlobClient.GetContainerReference("test");
            await Container.CreateIfNotExistsAsync();
            CloudBlockBlob blob = Container.GetBlockBlobReference(fileRequestObject.File.FileName);
            HashSet<string> blocklist = new HashSet<string>();
            var file = fileRequestObject.File;
            const int pageSizeInBytes = 10485760;
            long prevLastByte = 0;
            long bytesRemain = file.Length;

            byte[] bytes;

            using (MemoryStream ms = new MemoryStream())
            {
                var fileStream = file.OpenReadStream();
                await fileStream.CopyToAsync(ms);
                bytes = ms.ToArray();
            }

            // Upload each piece
                do
                {
                    long bytesToCopy = Math.Min(bytesRemain, pageSizeInBytes);
                    byte[] bytesToSend = new byte[bytesToCopy];

                    Array.Copy(bytes, prevLastByte, bytesToSend, 0, bytesToCopy);
                    prevLastByte += bytesToCopy;
                    bytesRemain -= bytesToCopy;

                    //create blockId
                    string blockId = Guid.NewGuid().ToString();
                    string base64BlockId = Convert.ToBase64String(Encoding.UTF8.GetBytes(blockId));

                    await blob.PutBlockAsync(
                        base64BlockId,
                        new MemoryStream(bytesToSend, true),
                        null
                        );

                    blocklist.Add(base64BlockId);

                } while (bytesRemain > 0);

            //post blocklist
            await blob.PutBlockListAsync(blocklist);



            return Ok();
            // For more information on protecting this API from Cross Site Request Forgery (CSRF) attacks, see https://go.microsoft.com/fwlink/?LinkID=717803
        }

public class FileRequestObject
    {
        public IFormFile File { get; set; }
    }

enter image description here enter image description here Подробнее см. https://www.red -gate.com / простой разговор / облако / платформа-как-сервис / лазурь-шарикообразным хранение части-4-загрузка-большие-сгустки /

...