【问题标题】:How to upload large files to azure container using .NET?如何使用 .NET 将大文件上传到 azure 容器?
【发布时间】:2019-03-01 18:52:18
【问题描述】:

我试图使用 Windows 窗体应用程序将大文件上传到 azure 容器。

由于文件很大,我无法将其作为单个块上传。

找到了一种将大文件作为一组块上传的方法。 我在这里发布代码,希望能帮助有类似要求的人。

【问题讨论】:

    标签: c# .net azure file-upload azure-blob-storage


    【解决方案1】:

    我们可以使用Block blobs将大文件上传到Azure容器。

    Block blobs 由块组成,每个块都由一个块 ID 标识。

    当我们将块上传到 blob 时,它与指定的块 blob 相关联,但在您提交包含新块 ID 的块列表之前,它不会成为 blob 的一部分。

    块 ID 是 blob 中长度相等的字符串。

    块客户端代码通常使用 base-64 编码将字符串标准化为相等的长度。 使用 base-64 编码时,预编码的字符串必须为 64 字节或更少。

    更多信息请阅读文档here

    以下代码将源文件拆分为多个字节数组,每个数组大小为 10MB。 使用 Put Block 操作将每个字节数组作为块上传。 这些块将与指定的Block blob 相关联。

    稍后使用 Put Block List 操作提交块 ID,该操作将使用块 ID 从上传的块创建 blob。

    public string UploadFile(string sourceFilePath)
    {
        try
        {
            string storageAccountConnectionString = "AZURE_CONNECTION_STRING";
            CloudStorageAccount StorageAccount = CloudStorageAccount.Parse(storageAccountConnectionString);
            CloudBlobClient BlobClient = StorageAccount.CreateCloudBlobClient();
            CloudBlobContainer Container = BlobClient.GetContainerReference("container-name");
            Container.CreateIfNotExists();
            CloudBlockBlob blob = Container.GetBlockBlobReference( Path.GetFileName(sourceFilePath) );
            HashSet<string> blocklist = new HashSet<string>();
    
            byte[] fileContent = File.ReadAllBytes(sourceFilePath);
            const int pageSizeInBytes = 10485760;
            long prevLastByte = 0;
            long bytesRemain = fileContent.Length;
    
            do
            {
                long bytesToCopy = Math.Min(bytesRemain, pageSizeInBytes);
                byte[] bytesToSend = new byte[bytesToCopy];
                Array.Copy(fileContent, prevLastByte, bytesToSend, 0, bytesToCopy);
                prevLastByte += bytesToCopy;
                bytesRemain -= bytesToCopy;
    
                //create blockId
                string blockId = Guid.NewGuid().ToString();
                string base64BlockId = Convert.ToBase64String(Encoding.UTF8.GetBytes(blockId));
    
                blob.PutBlock(
                    base64BlockId,
                    new MemoryStream(bytesToSend, true),
                    null
                    );
    
                blocklist.Add(base64BlockId);
    
            } while (bytesRemain > 0);
    
            //post blocklist
            blob.PutBlockList(blocklist);
    
            return "Success";
        }
        catch (Exception ex)
        {
            return ex.Message;
        }
    }
    

    【讨论】:

    • 感谢分享,对我帮助很大。
    猜你喜欢
    • 2021-12-18
    • 2021-03-05
    • 2019-06-26
    • 2020-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-29
    相关资源
    最近更新 更多