Как сжать файлы в zip и загрузить в хранилище больших двоичных объектов Azure?

#c# #stream #zip #azure-blob-storage

#c# #поток #zip #azure-blob-storage

Вопрос:

У меня странная проблема с этим фрагментом кода, который в основном архивирует файлы (документы) и загружает их в хранилище больших двоичных объектов.

v11SDK: (документы)

 var blockBlobClient = new BlockBlobClient(ConnectionString, ContainerName, "test-blob.zip");

// Saved zip is valid
// using (FileStream zipStream = new FileStream(@"C:UsersarturDesktoptest-local.zip", FileMode.OpenOrCreate))

// Uploaded zip is invalid
using (var stream = await blockBlobClient.OpenWriteAsync(true))
using (var archive  = new ZipArchive(stream, ZipArchiveMode.Create))
{
    var readmeEntry = archive .CreateEntry("Readme.txt");
    using (StreamWriter writer = new StreamWriter(readmeEntry.Open()))
    {
            writer.WriteLine("Information about this package.");
            writer.WriteLine("========================");
    }
    await stream.FlushAsync();
}
  

v12SDK: (документы)

 var blobClient = new BlobClient(ConnectionString, InputContainerName, "test-blob.zip");

using var stream = new MemoryStream();
using (var archive = new ZipArchive(stream, ZipArchiveMode.Create))
{
    var readmeEntry = archive.CreateEntry("Readme.txt");
    using StreamWriter writer = new StreamWriter(readmeEntry.Open());
    {
        writer.WriteLine("Information about this package.");
        writer.WriteLine("========================");
        await writer.FlushAsync();
    }
    stream.Position = 0;
    await blobClient.UploadAsync(stream, true);
    await stream.FlushAsync();
}
  

При сохранении zip-файла локально создается действительный zip-файл (164 байта). При сохранении zip-файла в хранилище больших двоичных объектов (с использованием эмулятора хранилища) создается недопустимый zip-файл (102 байта).
Я не могу понять, почему

Ответ №1:

Вот правильный код. Проблема заключалась в преждевременном удалении внутреннего потока ZipArchive. Обратите внимание, что в моем коде ниже я передал значение leaveInnerStreamOpen как true при создании ZipArchive, поскольку мы уже удаляем stream во внешнем использовании. Также для кода версии 11 я переключился на MemoryStream вместо OpenWrite потока больших двоичных объектов, поскольку у меня не было возможности установить позицию потока в 0, если мы используем OpenWrite. И вам не нужно никакой очистки 🙂

v11SDK:

         var blockBlobClient = new BlockBlobClient(ConnectionString, ContainerName, "test-blob.zip");
        using var stream = new MemoryStream();
        using (var archive = new ZipArchive(stream, ZipArchiveMode.Create, true))
        {
            var readmeEntry = archive.CreateEntry("Readme.txt");
            using (StreamWriter writer = new StreamWriter(readmeEntry.Open()))
            {
                writer.WriteLine("Information about this package.");
                writer.WriteLine("========================");
            }
        }
        stream.Position = 0;
        await blockBlobClient.UploadAsync(stream);
  

v12SDK:

         var blobClient = new BlobClient(ConnectionString, InputContainerName, "test-blob.zip");
        using var stream = new MemoryStream();
        using (var archive = new ZipArchive(stream, ZipArchiveMode.Create, true))
        {
            var readmeEntry = archive.CreateEntry("Readme.txt");
            using StreamWriter writer = new StreamWriter(readmeEntry.Open());
            {
                writer.WriteLine("Information about this package.");
                writer.WriteLine("========================");
            }
        }

        stream.Position = 0;
        await blobClient.UploadAsync(stream, true);
  

Комментарии:

1. Спасибо! Я пробовал v12SDK (отброшенный v11SDK), и теперь zip открывается, но он пуст.

2. да, оставьте значение leaveInnerStreamOpen = true, предложение сделать его true по умолчанию может быть проблематичным в другом сценарии, кроме загрузки больших двоичных объектов, а также это класс .net, который предназначен для общего назначения. Что касается пустого zip, это странно! Для меня это нормально с точно таким же кодом!