upload large files (> 1 GB) to azure blob storage through web api

前端 未结 1 1051
面向向阳花
面向向阳花 2021-01-07 05:02

we have an application(.Net core) that is hosted in azure app service and we are trying to upload large files to Azure blob through web API using Form data from UI. We have

相关标签:
1条回答
  • 2021-01-07 05:39

    According to your code, you want to upload a large file to Azure blob storage as blockblob. Please note that it has a limitation. For more details, please refer to the document

    The maximum size for a block blob created via Put Blob is 256 MB for version 2016-05-31 and later, and 64 MB for older versions. If your blob is larger than 256 MB for version 2016-05-31 and later, or 64 MB for older versions, you must upload it as a set of blocks

    So If you want to large files to azure block blob, pleae use the following steps:

    1. Read the whole file to bytes, and divide the file into smaller pieces in your code.

    • Maybe 8 MB for each pieces.

    2. Upload each piece with Put Block API.

    • In each request, it contains a blockid.

    3. Make up the blob with Put Block List API.

    • In this request, you need to put all the blockid in the body in ordered.

    For example :

    [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; }
        }
    
    

    For more details, please refer to https://www.red-gate.com/simple-talk/cloud/platform-as-a-service/azure-blob-storage-part-4-uploading-large-blobs/

    0 讨论(0)
提交回复
热议问题