#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, это странно! Для меня это нормально с точно таким же кодом!