使用SharpZipLib压缩打包多个内存中的文件

简介:
SharpZipLib是C#写的开源压缩解压缩组件,最近项目上遇到一个需求:根据用户选择的项目生成CSV文件并下载,后来改为同时生成2个CSV文件下载下来。想到的解决办法就是将2个CSV文件打包成一个Zip文件,然后供用户下载。

SharpZipLib可以通过很简单的代码就将多个文件打包成一个zip包,形如:

using (ZipFile zip = ZipFile.Create(@"E:\test.zip"))
{
zip.BeginUpdate();
ZipEntry e=new ZipEntry("a");
//添加文件
zip.Add(@"E:\a.csv");
zip.Add(@"E:\b.csv");
zip.CommitUpdate();
}

但是这里的问题是,zip.Add方法允许添加文件,但是不允许直接添加字符串或者byte[],但是我们做的是WebApplication,不希望是在Web服务器上把两个CSV文件生成后保存到硬盘上,然后调用上面的方法压缩硬盘上的文件。我们的文件应该都是在内存中生成,在内存中打包,然后直接把生成的zip文件的二进制流返回给用户,让用户下载。幸好该方法提供了一个IStaticDataSource接口参数,该接口有个返回Stream的GetSource方法,我们可以实现该接口,从而支持字符串文件的打包。

class StringDataSource : IStaticDataSource
{
public string Str { get; set; }

public StringDataSource(string str)
{
this.Str = str;
}

public Stream GetSource()
{
Stream s = new MemoryStream(Encoding.Default.GetBytes(Str));
return s;
}
}

实现了该接口后,那么我们压缩两个String成两个文本文件的包,代码就十分简单了:

using (ZipFile zip = ZipFile.Create(@"E:\test2.zip"))
{
zip.BeginUpdate();
StringDataSource d1 = new StringDataSource("this a test1");
StringDataSource d2 = new StringDataSource("压缩文件2的内容");
//添加文件
zip.Add(d1, "Test1.txt");
zip.Add(d2, "Test2.txt");
zip.CommitUpdate();
}

上面的代码还是在硬盘上生成了test2.zip,幸好ZipFile.Create方法支持Stream参数,于是可以将代码改为:

MemoryStream stream=new MemoryStream();
using (ZipFile zip = ZipFile.Create(stream))
{
zip.BeginUpdate();
StringDataSource d1 = new StringDataSource("this a test1");
StringDataSource d2 = new StringDataSource("压缩文件2的内容");
//添加文件
zip.Add(d1, "Test1.txt");
zip.Add(d2, "Test2.txt");
zip.CommitUpdate();
}

然后将stream继续Render给用户即可。

同样的方式,如果是在内存中生成了二进制文件,也可以使用实现IStaticDataSource接口的方式来打包。

目录
相关文章
|
6月前
|
Unix 程序员 Linux
【OSTEP】动态内存开辟 | 内存API常见错误 | UNIX: brk/sbrk 系统调用 | mmap创建匿名映射区域 | mmap创建以文件为基础的映射区域
【OSTEP】动态内存开辟 | 内存API常见错误 | UNIX: brk/sbrk 系统调用 | mmap创建匿名映射区域 | mmap创建以文件为基础的映射区域
180 0
|
4月前
|
存储 缓存 Java
释放C盘空间:释放Windows休眠文件和关闭虚拟内存
在 Windows 11 专业版中,可以通过以下步骤来释放休眠文件(Hibernate File),以释放磁盘空间。休眠文件是系统休眠(Hibernate)功能所需要的文件,它保存了系统的当前状态,以便在休眠状态下恢复。如果你不使用休眠功能,如果因为C盘空间不足,可以考虑释放这个文件来腾出磁盘空间。
4660 0
|
4月前
|
人工智能 算法 BI
【经典问题】给两个文件,分别有100亿个整数,我们只有1G内存,如何找到两个文件交集?
【1月更文挑战第26天】【经典问题】给两个文件,分别有100亿个整数,我们只有1G内存,如何找到两个文件交集?
|
4月前
|
存储 编译器 C语言
learn_C_deep_10 extern在多文件下的理解、struct 关键字的理解与柔性数组、union 的内存级布局理解、enum 关键字的基本理解、typedef 的理解与分类、关键字总结
learn_C_deep_10 extern在多文件下的理解、struct 关键字的理解与柔性数组、union 的内存级布局理解、enum 关键字的基本理解、typedef 的理解与分类、关键字总结
|
4月前
|
移动开发 安全 图形学
如何绕过某讯手游保护系统并从内存中获取Unity3D引擎的Dll文件
如何绕过某讯手游保护系统并从内存中获取Unity3D引擎的Dll文件
30 0
|
5月前
|
移动开发 安全 图形学
如何绕过某讯手游保护系统并从内存中获取Unity3D引擎的Dll文件
通过动态分析了它的保护方法,通过改源码刷机的方法绕过了它的保护方案(也可通过hook libc.so中的execve函数绕过保护),接下来就可以直接使用GameGuardain这个神奇附加上去进行各种骚操作了。这里主要讲一下如何去从内存中获取Assembly-CSharp.dll 和 Assembly-CSharp-fristpass.dll文件。
|
6月前
|
jenkins Java Shell
Jenkins 打包shell出现gradle命令不存在,jvm内存溢出
Jenkins 打包shell出现gradle命令不存在,jvm内存溢出
60 4
|
6月前
|
存储 缓存 NoSQL
轻松突破文件IO瓶颈:内存映射mmap技术
轻松突破文件IO瓶颈:内存映射mmap技术
|
7月前
|
测试技术 C#
C#不通过byte[],直接对内存映射文件复制内存
C#不通过byte[],直接对内存映射文件复制内存
|
7月前
|
存储 缓存 分布式数据库
[笔记]Windows核心编程《十七》内存映射文件(二)
[笔记]Windows核心编程《十七》内存映射文件(二)