简体   繁体   English

如何从C#内存中的文件创建ZipArchive?

[英]How to create ZipArchive from files in memory in C#?

Is it somehow possible to create a ZipArchive from the file(s) in memory (and not actually on the disk). 是否有可能从内存中的文件创建ZipArchive(而不是实际在磁盘上)。

Following is the use case: Multiple files are received in an IEnumerable<HttpPostedFileBase> variable. 以下是用例:IEnumerable<HttpPostedFileBase>变量中接收多个文件。 I want to zip all these files together using ZipArchive . 我想使用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. 问题是ZipArchive只允许CreateEntryFromFile ,它需要一个文件路径,因为我只有内存中的文件。

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? 问题:有没有办法在ZipArchive使用'stream'创建'entry',这样我就可以直接在zip中输入文件的内容?

I don't want to first save the files, create the zip (from the saved files' paths) and then delete the individual files. 我不想先保存文件,创建zip(从保存文件的路径),然后删除单个文件。

Here, attachmentFiles is IEnumerable<HttpPostedFileBase> 这里, attachmentFilesIEnumerable<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);
        }
    }
    ...
}

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. 是的,您可以使用ZipArchive.CreateEntry方法执行此操作,因为@AngeloReis在注释中指出,并在此处描述了稍微不同的问题。

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

First off thanks @Alex for the perfect answer. 首先感谢@Alex的完美答案。
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 System.IO.Compression.ZipFileExtensions的帮助下

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM