Как загрузить большие файлы в контейнер Azure, используя .NET? - PullRequest
0 голосов
/ 01 марта 2019

Я пытался загрузить большие файлы в контейнер Azure, используя приложение Windows Form.

Поскольку размер файла был велик, я не мог загрузить его как один блок.

Был найден способ загрузки больших файлов в виде набора блоков.Я публикую здесь код в надежде помочь кому-то, имеющему подобное требование.

1 Ответ

0 голосов
/ 01 марта 2019

Мы можем загружать большие файлы в контейнер Azure, используя Block blobs.

Block blobs состоят из блоков, каждый из которых идентифицируется идентификатором блока.

Когда мы загружаем блок в BLOB-объект, он связывается с указанным BLOB-объектом, но онне становится частью большого двоичного объекта, пока вы не зафиксируете список блоков, который включает в себя идентификатор нового блока.

Идентификаторы блоков - это строки одинаковой длины внутри большого двоичного объекта.

Блочный клиентский код обычно использует кодировку base-64 для нормализации строк равной длины.При использовании кодировки base-64 предварительно закодированная строка должна иметь длину не более 64 байт.

Для получения дополнительной информации ознакомьтесь с документацией здесь .

Следующий код разбиваетисходный файл в несколько байтовых массивов размером 10 МБ каждый.Каждый байтовый массив загружается в виде блоков с использованием операции Put Block .Эти блоки будут связаны с указанной Block blob.

Позже идентификаторы блоков фиксируются с помощью операции Put Block List , которая создаст большой двоичный объект из загруженных блоков.используя идентификаторы блоков.

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