Создать в памяти zip из файла

Предполагается ли, что DeflateStream создает заархивированный поток, который можно хранить как стандартный архив .zip?

Я пытаюсь создать zip в памяти (для удаленной отправки) из локального файла. Я использовал DeflateStream, чтобы получить сжатый массив байтов из файла на локальном диске:

public static byte[] ZipFile(string csvFullPath)
    {
        using (FileStream csvStream = File.Open(csvFullPath, FileMode.Open, FileAccess.Read))
        {
            using (MemoryStream compressStream = new MemoryStream())
            {
                using (DeflateStream deflateStream = new DeflateStream(compressStream, CompressionLevel.Optimal))
                {
                    csvStream.CopyTo(deflateStream);
                    deflateStream.Close();
                    return compressStream.ToArray();
                }
            }
        }
    }

Это прекрасно работает. Однако, когда я выгружаю полученные байты в zip-файл:

byte[] zippedBytes = ZipFile(FileName);
File.WriteAllBytes("Sample.zip", zippedBytes);

Я не могу открыть полученный архив .zip с помощью встроенных в Windows функций .zip (или с помощью любого другого стороннего инструмента для архивирования).

Альтернативой, которую я планирую сейчас, является использование ZipArchive, однако это потребует создания временных файлов на диске (сначала скопируйте файл в отдельный каталог, затем заархивируйте его, затем прочтите его в массив байтов и затем удалите)


person Jan    schedule 25.05.2016    source источник
comment
Вы должны использовать ZipArchive класс. Он работает с потоками и не требует временных файлов.   -  person Ivan Stoev    schedule 25.05.2016


Ответы (1)


Вы можете использовать эту прекрасную библиотеку https://dotnetzip.codeplex.com/

или вы можете использовать ZipArchive, и он неплохо работает с MemoryStream:

public static byte[] ZipFile(string csvFullPath)
{
    using (FileStream csvStream = File.Open(csvFullPath, FileMode.Open, FileAccess.Read))
    {
        using (MemoryStream zipToCreate = new MemoryStream())
        {
            using (ZipArchive archive = new ZipArchive(zipToCreate, ZipArchiveMode.Create, true))
            {
                ZipArchiveEntry fileEntry = archive.CreateEntry(Path.GetFileName(csvFullPath));
                using (var entryStream = fileEntry.Open())
                {
                    csvStream.CopyTo(entryStream);
                }
            }

            return zipToCreate.ToArray();
        }
    }
}
person Sergey L    schedule 25.05.2016
comment
Код работает нормально, но если я сбрасываю байты в файл .zip, то его нельзя открыть (якобы поврежденный архив). Кстати. двоичное содержимое этого файла почти идентично файлу, созданному в рассматриваемом примере - person Jan; 25.05.2016
comment
ваш код привел меня в правильное направление, но на самом деле ему нужно избавиться от ZipArchive перед использованием потока памяти (плюс для leaveOpen необходимо установить значение true). Кредиты принадлежат этому ответу: stackoverflow.com / questions / 12347775 / - person Jan; 25.05.2016