Как создать ZipArchive из файлов в памяти на С#?

Возможно ли создать ZipArchive из файла (ов) в памяти (а не на самом деле на диске).

Ниже приведен пример использования: Несколько файлов получены в переменной IEnumerable<HttpPostedFileBase>. Я хочу объединить все эти файлы, используя ZipArchive. Проблема в том, что ZipArchive допускает только CreateEntryFromFile, который ожидает путь к файлу, где, поскольку у меня есть только файлы в памяти.

Вопрос: Есть ли способ использовать "поток" для создания "записи" в ZipArchive, чтобы я мог напрямую помещать содержимое файла в zip?

Я не хочу сначала сохранять файлы, создавать zip (из путей сохраненных файлов), а затем удалять отдельные файлы.

Здесь attachmentFiles есть IEnumerable<HttpPostedFileBase>

using (var ms = new MemoryStream())
{
    using (var zipArchive = new ZipArchive(ms, ZipArchiveMode.Create, true))
    {
        foreach (var attachment in attachmentFiles)
        {
            zipArchive.CreateEntryFromFile(Path.GetFullPath(attachment.FileName), Path.GetFileName(attachment.FileName),
                                CompressionLevel.Fastest);
        }
    }
    ...
}

Ответ 1

Да, вы можете сделать это, используя метод ZipArchive.CreateEntry, как отметил @AngeloReis в комментариях, и описал здесь для немного другой проблемы.

Тогда ваш код будет выглядеть так:

using (var ms = new MemoryStream())
{
    using (var zipArchive = new ZipArchive(ms, ZipArchiveMode.Create, true))
    {
        foreach (var attachment in attachmentFiles)
        {
            var entry = zipArchive.CreateEntry(attachment.FileName, CompressionLevel.Fastest);
            using (var entryStream = entry.Open())
            {
                attachment.InputStream.CopyTo(entryStream);
            }
        }
    }
    ...
}

Ответ 2

Прежде всего, спасибо @Alex за отличный ответ.
Также для сценария вам необходимо прочитать из файловых систем:

using (var ms = new MemoryStream())
{
    using (var zipArchive = new ZipArchive(ms, ZipArchiveMode.Create, true))
    {
        foreach (var file in filesAddress)
        {
            zipArchive.CreateEntryFromFile(file, Path.GetFileName(file));
        }
    }

    ...
}

с помощью System.IO.Compression.ZipFileExtensions