C#创建压缩文件的实现代码

2019-12-30 17:18:13刘景俊

代码并不复杂且添加了详细的注释,因此不再赘言。此时已经完成了把文件加入压缩包的功能,压缩包中的内容如下:

C#,压缩文件,创建压缩文件,生成压缩包

注意,web.dll 文件在 share 文件夹中。

把内存中的数据添加到压缩包

有时我们要压缩的对象并不是磁盘上的文件,而是内存中的数据。比如数据库查询操作的结果中有一些字符串,希望把这些字符串写入到压缩包中的文本文件中。当然可以先把这些字符串保存到磁盘上的文件中,然后再通过前面例子中的方法写入压缩包,这也可以完成任务,却不是高效的方法。首先磁盘 IO 很慢也很昂贵,另外在一些 web 应用环境中你是没有权限写文件的。这就要求我们直接把数据写入到压缩包中:


//我们有一个字符串,希望直接写入到压缩包中的City.csv文件中。
byte[] string1 = Encoding.UTF8.GetBytes("Washington,ShangHai,TianJin,DongJing");
using (FileStream fsOut = File.Create("test1.zip"))
{
 using (ZipOutputStream zipStream = new ZipOutputStream(fsOut))
 {
  ZipEntry entry = new ZipEntry("City.csv");
  entry.DateTime = DateTime.Now;
  zipStream.PutNextEntry(entry);
  //Write方法和前面用的StreamUtils.Copy方法差不多,不过这里操作的是byte数组。
  zipStream.Write(string1, 0, string1.Length);
  zipStream.CloseEntry();
  zipStream.IsStreamOwner = false;
  zipStream.Finish();
  zipStream.Close();
 }
}

这次我们把内存中的一个字符串直接写入了压缩包中得 City.csv 文件。看上去还不错,至少代码看上去还算清爽。接下来看看我们还能干些什么?

把压缩包保存在内存中

上面的例子中我们提到,有时是没有权限写文件的,那还怎么创建压缩文件呀?太矛盾了!其实现实中还真有这样的用例。比如你有一个网站,当用户点击下载按钮时,你需要把数据保存到压缩文件中然后返回给用户。整个过程中你是写不了文件的,只能通过操作内存来实现:


byte[] string1 = Encoding.UTF8.GetBytes("Washington,ShangHai,TianJin,DongJing");
byte[] result = null;
using (MemoryStream ms = new MemoryStream())
{
 using (ZipOutputStream zipStream = new ZipOutputStream(ms))
 {
  ZipEntry entry = new ZipEntry("City.csv");
  entry.DateTime = DateTime.Now;
  zipStream.PutNextEntry(entry);
  zipStream.Write(string1, 0, string1.Length);
  zipStream.CloseEntry();
  zipStream.IsStreamOwner = false;
  zipStream.Finish();
  zipStream.Close();
  ms.Position = 0;

  //压缩后的数据被保存到了byte[]数组中。
  result = ms.ToArray();
 }
}

现在 byte 数组 result 中就是压缩包的数据。如果希望通过 HttpResponse 返回给用户,就可以通过调用 HttpResponse 的 BinaryWrite 方法实现,只要把 result 作为参数即可。