Отправка большого двоичного объекта с помощью .NET

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

Предварительные требования

Отправка данных в блочный BLOB-объект

Для отправки данных в блочный BLOB-объект можно использовать один из следующих методов:

При использовании этих методов отправки клиентская библиотека может вызвать либо Put BLOB-объект , либо ряд вызовов Put Block , за которыми следует Поместить список блокировок. Это поведение зависит от общего размера объекта и настройки параметров передачи данных .

Чтобы открыть поток в хранилище BLOB-объектов и выполнить запись в этот поток, используйте один из следующих методов:

Отправка блочного BLOB-объекта из локального пути к файлу

В следующем примере передается блочный BLOB-объект из локального пути к файлу:

public static async Task UploadFromFileAsync(
    BlobContainerClient containerClient,
    string localFilePath)
{
    string fileName = Path.GetFileName(localFilePath);
    BlobClient blobClient = containerClient.GetBlobClient(fileName);

    await blobClient.UploadAsync(localFilePath, true);
}

Отправка блочного BLOB-объекта из потока

В следующем примере передается блочный BLOB-объект путем создания объекта Stream и отправки потока.

public static async Task UploadFromStreamAsync(
    BlobContainerClient containerClient,
    string localFilePath)
{
    string fileName = Path.GetFileName(localFilePath);
    BlobClient blobClient = containerClient.GetBlobClient(fileName);

    FileStream fileStream = File.OpenRead(localFilePath);
    await blobClient.UploadAsync(fileStream, true);
    fileStream.Close();
}

Отправка блочного BLOB-объекта из объекта BinaryData

В следующем примере передается блочный BLOB-объект из объекта BinaryData .

public static async Task UploadFromBinaryDataAsync(
    BlobContainerClient containerClient,
    string localFilePath)
{
    string fileName = Path.GetFileName(localFilePath);
    BlobClient blobClient = containerClient.GetBlobClient(fileName);

    FileStream fileStream = File.OpenRead(localFilePath);
    BinaryReader reader = new BinaryReader(fileStream);

    byte[] buffer = new byte[fileStream.Length];
    reader.Read(buffer, 0, buffer.Length);
    BinaryData binaryData = new BinaryData(buffer);

    await blobClient.UploadAsync(binaryData, true);

    fileStream.Close();
}

Отправка блочного BLOB-объекта из строки

В следующем примере передается блочный BLOB-объект из строки:

public static async Task UploadFromStringAsync(
    BlobContainerClient containerClient,
    string blobName)
{
    BlobClient blobClient = containerClient.GetBlobClient(blobName);
    string blobContents = "Sample blob data";

    await blobClient.UploadAsync(BinaryData.FromString(blobContents), overwrite: true);
}

Отправка в поток в Хранилище BLOB-объектов

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

public static async Task UploadToStreamAsync(
    BlobContainerClient containerClient,
    string localDirectoryPath)
{
    string zipFileName = Path.GetFileName(
        Path.GetDirectoryName(localDirectoryPath)) + ".zip";

    BlockBlobClient blockBlobClient = containerClient.GetBlockBlobClient(zipFileName);

    using (Stream stream = await blockBlobClient.OpenWriteAsync(true))
    {
        using (ZipArchive zip = new ZipArchive(stream, ZipArchiveMode.Create, leaveOpen: false))
        {
            foreach (var fileName in Directory.EnumerateFiles(localDirectoryPath))
            {
                using (var fileStream = File.OpenRead(fileName))
                {
                    var entry = zip.CreateEntry(
                        Path.GetFileName(fileName), CompressionLevel.Optimal);
                    using (var innerFile = entry.Open())
                    {
                        await fileStream.CopyToAsync(innerFile);
                    }
                }
            }
        }
    }
}

Отправка блочного BLOB-объекта с параметрами конфигурации

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

Указание параметров передачи данных при отправке

Значения можно настроить в StorageTransferOptions , чтобы повысить производительность операций передачи данных. В следующем примере кода показано, как задать значения для StorageTransferOptions и включить параметры в составе экземпляра BlobUploadOptions . Значения, приведенные в этом примере, не предназначены для рекомендации. Чтобы правильно настроить эти значения, необходимо учитывать конкретные потребности приложения.

public static async Task UploadWithTransferOptionsAsync(
    BlobContainerClient containerClient,
    string localFilePath)
{
    string fileName = Path.GetFileName(localFilePath);
    BlobClient blobClient = containerClient.GetBlobClient(fileName);

    var transferOptions = new StorageTransferOptions
    {
        // Set the maximum number of parallel transfer workers
        MaximumConcurrency = 2,

        // Set the initial transfer length to 8 MiB
        InitialTransferSize = 8 * 1024 * 1024,

        // Set the maximum length of a transfer to 4 MiB
        MaximumTransferSize = 4 * 1024 * 1024
    };

    var uploadOptions = new BlobUploadOptions()
    {
        TransferOptions = transferOptions
    };

    FileStream fileStream = File.OpenRead(localFilePath);
    await blobClient.UploadAsync(fileStream, uploadOptions);
    fileStream.Close();
}

Дополнительные сведения о настройке параметров передачи данных см. в статье Настройка производительности при отправке и скачивании с помощью .NET.

Указание параметров проверки передачи при отправке

Вы можете указать параметры проверки передачи, чтобы убедиться, что данные отправлены правильно и не были изменены во время передачи. Параметры проверки передачи можно определить на уровне клиента с помощью BlobClientOptions, который применяет параметры проверки ко всем методам, вызываемым из экземпляра BlobClient .

Вы также можете переопределить параметры проверки передачи на уровне метода с помощью BlobUploadOptions. В следующем примере кода показано, BlobUploadOptions как создать объект и указать алгоритм для создания контрольной суммы. Затем контрольная сумма используется службой для проверки целостности данных отправленного содержимого.

public static async Task UploadWithChecksumAsync(
    BlobContainerClient containerClient,
    string localFilePath)
{
    string fileName = Path.GetFileName(localFilePath);
    BlobClient blobClient = containerClient.GetBlobClient(fileName);

    var validationOptions = new UploadTransferValidationOptions
    {
        ChecksumAlgorithm = StorageChecksumAlgorithm.Auto
    };

    var uploadOptions = new BlobUploadOptions()
    {
        TransferValidation = validationOptions
    };

    FileStream fileStream = File.OpenRead(localFilePath);
    await blobClient.UploadAsync(fileStream, uploadOptions);
    fileStream.Close();
}

В следующей таблице показаны доступные параметры для алгоритма контрольной суммы, определенные в StorageChecksumAlgorithm:

Имя Значение Описание
Auto 0 (рекомендуется). Позволяет библиотеке выбрать алгоритм. Разные версии библиотек могут выбирать разные алгоритмы.
None 1 Не выбран алгоритм. Не вычисляйте и не запрашивайте контрольные суммы.
MD5 2 Стандартный хэш-алгоритм MD5.
StorageCrc64 3 Настраиваемый 64-разрядный CRC службы хранилища Azure.

Примечание

Если контрольная сумма, указанная в запросе, не соответствует контрольной сумме, вычисленной службой, операция отправки завершается ошибкой. Операция не повторяется при использовании политики повтора по умолчанию. В .NET RequestFailedException создается с кодом состояния 400 и кодом Md5Mismatch ошибки или Crc64Mismatchв зависимости от используемого алгоритма.

Отправка с помощью тегов индекса

Теги индекса больших двоичных объектов классифицируют данные в учетной записи хранения с помощью атрибутов тегов типа "ключ-значение". Эти теги автоматически индексируются и представляются в виде многомерного индекса с поддержкой поиска для упрощения нахождения данных. Вы можете добавить теги в экземпляр BlobUploadOptions и передать этот экземпляр в UploadAsync метод .

В следующем примере передается блочный BLOB-объект с тегами индекса:

public static async Task UploadBlobWithTagsAsync(
    BlobContainerClient containerClient,
    string blobName)
{
    BlobClient blobClient = containerClient.GetBlobClient(blobName);
    string blobContents = "Sample blob data";

    BlobUploadOptions options = new BlobUploadOptions();
    options.Tags = new Dictionary<string, string>
    {
        { "Sealed", "false" },
        { "Content", "image" },
        { "Date", "2020-04-20" }
    };

    await blobClient.UploadAsync(BinaryData.FromString(blobContents), options);
}

Установка уровня доступа к BLOB-объекту при отправке

Вы можете задать уровень доступа к BLOB-объекту при отправке с помощью класса BlobUploadOptions . В следующем примере кода показано, как задать уровень доступа при отправке большого двоичного объекта:

public static async Task UploadWithAccessTierAsync(
    BlobContainerClient containerClient,
    string localFilePath)
{
    string fileName = Path.GetFileName(localFilePath);
    BlockBlobClient blockBlobClient = containerClient.GetBlockBlobClient(fileName);

    var uploadOptions = new BlobUploadOptions()
    {
        AccessTier = AccessTier.Cool
    };

    FileStream fileStream = File.OpenRead(localFilePath);
    await blockBlobClient.UploadAsync(fileStream, uploadOptions);
    fileStream.Close();
}

Настройка уровня доступа разрешена только для блочных BLOB-объектов. Для блочного BLOB-объекта Hotможно задать уровень доступа , Cool, Coldили Archive. Чтобы задать для уровня доступа значение Cold, необходимо использовать минимальную версию клиентской библиотеки 12.15.0.

Дополнительные сведения об уровнях доступа см. в статье Общие сведения об уровнях доступа.

Отправка блочного BLOB-объекта путем промежуточного хранения блоков и фиксации

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

public static async Task UploadBlocksAsync(
    BlobContainerClient blobContainerClient,
    string localFilePath,
    int blockSize)
{
    string fileName = Path.GetFileName(localFilePath);
    BlockBlobClient blobClient = blobContainerClient.GetBlockBlobClient(fileName);

    FileStream fileStream = File.OpenRead(localFilePath);
    ArrayList blockIDArrayList = new ArrayList();
    byte[] buffer;

    var bytesLeft = (fileStream.Length - fileStream.Position);

    while (bytesLeft > 0)
    {
        if (bytesLeft >= blockSize)
        {
            buffer = new byte[blockSize];
            await fileStream.ReadAsync(buffer, 0, blockSize);
        }
        else
        {
            buffer = new byte[bytesLeft];
            await fileStream.ReadAsync(buffer, 0, Convert.ToInt32(bytesLeft));
            bytesLeft = (fileStream.Length - fileStream.Position);
        }

        using (var stream = new MemoryStream(buffer))
        {
            string blockID = Convert.ToBase64String(
                Encoding.UTF8.GetBytes(Guid.NewGuid().ToString()));

            blockIDArrayList.Add(blockID);
            await blobClient.StageBlockAsync(blockID, stream);
        }
        bytesLeft = (fileStream.Length - fileStream.Position);
    }

    string[] blockIDArray = (string[])blockIDArrayList.ToArray(typeof(string));

    await blobClient.CommitBlockListAsync(blockIDArray);
}

Ресурсы

Дополнительные сведения об отправке больших двоичных объектов с помощью клиентской библиотеки Хранилище BLOB-объектов Azure для .NET см. в следующих ресурсах.

Операции REST API

Пакет Azure SDK для .NET содержит библиотеки, которые создаются на основе REST API Azure, что позволяет взаимодействовать с операциями REST API через знакомые парадигмы .NET. Методы клиентской библиотеки для отправки больших двоичных объектов используют следующие операции REST API:

Примеры кода

См. также раздел