How to create ZipArchive from files in memory in C

2020-02-09 08:08发布

Is it somehow possible to create a ZipArchive from the file(s) in memory (and not actually on the disk).

Following is the use case: Multiple files are received in an IEnumerable<HttpPostedFileBase> variable. I want to zip all these files together using ZipArchive. The problem is that ZipArchive only allows CreateEntryFromFile, which expects a path to the file, where as I just have the files in memory.

Question: Is there a way to use a 'stream' to create the 'entry' in ZipArchive, so that I can directly put in the file's contents in the zip?

I don't want to first save the files, create the zip (from the saved files' paths) and then delete the individual files.

Here, attachmentFiles is 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);
        }
    }
    ...
}

2条回答
ら.Afraid
2楼-- · 2020-02-09 08:45

Yes, you can do this, using the ZipArchive.CreateEntry method, as @AngeloReis pointed out in the comments, and described here for a slightly different problem.

Your code would then look like this:

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);
            }
        }
    }
    ...
}
查看更多
对你真心纯属浪费
3楼-- · 2020-02-09 08:48

First off thanks @Alex for the perfect answer.
Also for the scenario you need to read from file systems :

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));
        }
    }

    ...
}

with the help of System.IO.Compression.ZipFileExtensions

查看更多
登录 后发表回答