从流创建 Zip 文件并下载它

2024-03-07

我有一个 DataTable,我想将其转换为 xml,然后使用 DotNetZip 对其进行压缩。最后用户可以通过Asp.Net网页下载它。 我的代码在下面

    dt.TableName = "Declaration";

    MemoryStream stream = new MemoryStream();
    dt.WriteXml(stream);

    ZipFile zipFile = new ZipFile();
    zipFile.AddEntry("Report.xml", "", stream);
    Response.ClearContent();
    Response.ClearHeaders();
    Response.AppendHeader("content-disposition", "attachment; filename=Report.zip");

    zipFile.Save(Response.OutputStream);
    //Response.Write(zipstream);
    zipFile.Dispose();

zip 文件中的 xml 文件为空。


2件事。首先,如果保留现有的代码设计,则需要在将 MemoryStream 写入条目之前对其执行 Seek()。

dt.TableName = "Declaration"; 

MemoryStream stream = new MemoryStream(); 
dt.WriteXml(stream); 
stream.Seek(0,SeekOrigin.Begin);   // <-- must do this after writing the stream!

using (ZipFile zipFile = new ZipFile())
{
  zipFile.AddEntry("Report.xml", "", stream); 
  Response.ClearContent(); 
  Response.ClearHeaders(); 
  Response.AppendHeader("content-disposition", "attachment; filename=Report.zip"); 

  zipFile.Save(Response.OutputStream); 
}

即使您保留这种设计,我也会建议使用 using() 子句,正如我所展示的,以及所有DotNetZip 示例 http://dotnetzip.codeplex.com/wikipage?title=Examples,代替调用 Dispose()。 using() 子句在出现故障时更加可靠。

现在你可能想知道,为什么在调用AddEntry()之前需要在MemoryStream中查找呢?原因是,AddEntry() 旨在支持那些传递位置很重要的流的调用者。在这种情况下,调用者需要从流中读取条目数据,使用流的当前位置。 AddEntry() 支持这一点。因此,请在调用 AddEntry() 之前设置流中的位置。

但是,更好的选择是修改您的代码以使用接受 WriteDelegate 的 AddEntry() 的重载 http://cheeso.members.winisp.net/DotNetZipHelp/html/633c4280-51ca-cc82-b5b5-86bbe9b2e947.htm。它是专门为将数据集添加到 zip 文件中而设计的。您的原始代码将数据集写入内存流,然后在该流上查找,并将流的内容写入 zip 中。如果您只写入一次数据,那么会更快更容易,这就是 WriteDelegate 允许您执行的操作。代码如下所示:

dt.TableName = "Declaration"; 
Response.ClearContent(); 
Response.ClearHeaders(); 
Response.ContentType = "application/zip";
Response.AppendHeader("content-disposition", "attachment; filename=Report.zip"); 

using(Ionic.Zip.ZipFile zipFile = new Ionic.Zip.ZipFile())
{
    zipFile.AddEntry("Report.xml", (name,stream) => dt.WriteXml(stream) );
    zipFile.Save(Response.OutputStream); 
}

这会将数据集直接写入 zip 文件中的压缩流中。非常高效!没有双缓冲。匿名委托在 ZipFile.Save() 时被调用。仅执行一次写入(+压缩)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从流创建 Zip 文件并下载它 的相关文章

随机推荐