在 C# 中从内存中的多个文件创建 Zip 存档
当文件当前位于内存中时,有没有办法创建包含多个文件的 Zip 存档? 我想要保存的文件实际上只是文本,并且存储在我的应用程序中的字符串类中。 但我想将多个文件保存在一个独立的存档中。 它们都可以位于存档的根目录中。
如果能够使用 SharpZipLib 来完成此操作,那就太好了。
Is there a way to create a Zip archive that contains multiple files, when the files are currently in memory? The files I want to save are really just text only and are stored in a string class in my application. But I would like to save multiple files in a single self-contained archive. They can all be in the root of the archive.
It would be nice to be able to do this using SharpZipLib.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
为此,请使用
ZipEntry
和PutNextEntry()
。 下面展示了如何对文件执行此操作,但对于内存中的对象只需使用 MemoryStreamUse
ZipEntry
andPutNextEntry()
for this. The following shows how to do it for a file, but for an in-memory object just use a MemoryStream使用 SharpZipLib 来实现这一点似乎相当复杂。 在 DotNetZip 中这要容易得多。 在 v1.9 中,代码如下所示:
上面的代码假设 stringContent{1,2,3} 包含要存储在 zip 存档中的文件(或条目)中的数据。 第一个条目是“Readme.txt”,它存储在 zip 存档的顶层“目录”中。 接下来的两个条目存储在 zip 存档的“readings”目录中。
字符串以默认编码进行编码。 AddEntry() 有一个重载(此处未显示),它允许您显式指定要使用的编码。
如果内容位于流或字节数组中,而不是字符串中,则 AddEntry() 存在接受这些类型的重载。 还有接受 Write 委托的重载,这是一种被调用以将数据写入 zip 的方法。 例如,这可以轻松地将数据集保存到 zip 文件中。
DotNetZip 是免费且开源的。
Using SharpZipLib for this seems pretty complicated. This is so much easier in DotNetZip. In v1.9, the code looks like this:
The code above assumes stringContent{1,2,3} contains the data to be stored in the files (or entries) in the zip archive. The first entry is "Readme.txt" and it is stored in the top level "Directory" in the zip archive. The next two entries are stored in the "readings" directory in the zip archive.
The strings are encoded in the default encoding. There is an overload of AddEntry(), not shown here, that allows you to explicitly specify the encoding to use.
If you have the content in a stream or byte array, not a string, there are overloads for AddEntry() that accept those types. There are also overloads that accept a Write delegate, a method of yours that is invoked to write data into the zip. This works for easily saving a DataSet into a zip file, for example.
DotNetZip is free and open source.
该函数应该从数据流创建一个字节数组:为了简单起见,我创建了一个简单的接口来处理文件
This function should create a byte array from a stream of data: I've created a simple interface for handling files for simplicity
是的,您可以使用 SharpZipLib 来执行此操作 - 当您需要提供要写入的流时,请使用
MemoryStream
。Yes, you can use SharpZipLib to do this - when you need to supply a stream to write to, use a
MemoryStream
.我遇到了这个问题,使用我创建这个类的 MSDN 示例:
然后您可以像这样使用它:
您可以将
MemoryStream
(或任何Stream
)传递给ZipSticle.Add
例如:I come across this problem, using the MSDN example I created this class:
You can then use it like this:
You can pass a
MemoryStream
(or anyStream
) toZipSticle.Add
such as:请注意,这个答案已经过时了; 从 .Net 4.5 开始,ZipArchive 类允许在内存中压缩文件。 请参阅下面 johnny 5 的回答了解如何使用它。
您也可以做一些不同的事情,使用用于存储所有字符串的可序列化对象
然后,您可以将其序列化为流来保存它。
为了节省空间,您可以使用 GZipStream(来自 System.IO. Compression)来压缩它。 (注意:GZip 是流压缩,而不是多个文件的存档)。
也就是说,当然,如果您实际上需要的是保存数据,而不是为其他软件以特定格式压缩一些文件。
此外,这还允许您保存除字符串之外的更多类型的数据。
Note this answer is outdated; since .Net 4.5, the
ZipArchive
class allows zipping files in-memory. See johnny 5's answer below for how to use it.You could also do it a bit differently, using a Serializable object to store all strings
Then, you could serialize it into a stream to save it.
To save on space you could use GZipStream (From System.IO.Compression) to compress it. (note: GZip is stream compression, not an archive of multiple files).
That is, of course if what you need is actually to save data, and not zip a few files in a specific format for other software.
Also, this would allow you to save many more types of data except strings.
我通过添加
MemoryStream
作为不同 Excel 文件的源来利用 Cheeso 的答案。 当我下载 zip 文件时,文件中什么也没有。 这可能是我们尝试通过 AJAX 创建和下载文件的方式。为了将不同 Excel 文件的内容包含在 Zip 中,我必须将每个文件添加为
byte[]
。I was utilizing Cheeso's answer by adding
MemoryStream
s as the source of the different Excel files. When I downloaded the zip, the files had nothing in them. This could be the way we were getting around trying to create and download a file over AJAX.To get the contents of the different Excel files to be included in the Zip, I had to add each of the files as a
byte[]
.使用 StringReader 读取字符串对象并将它们公开为 Stream 。
这应该可以很容易地将它们提供给您的 zip 构建代码。
Use a StringReader to read from your string objects and expose them as Stream s.
That should make it easy to feed them to your zip-building code.