我有一个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文件为空。
发布于 2010-02-16 01:32:47
两件事。首先,如果您保留现有的代码设计,则需要在将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()子句来代替调用Dispose(),正如我已经展示过的,并且在所有DotNetZip examples中都有描述。在失败的情况下,using()子句更可靠。
现在您可能想知道,为什么在调用AddEntry()之前必须在MemoryStream中查找?原因是,AddEntry()被设计为支持那些在位置很重要的地方传递流的调用者。在这种情况下,调用方需要使用流的当前位置从流中读取条目数据。AddEntry()支持这一点。因此,请在调用AddEntry()之前设置流中的位置。
但是,更好的选择是修改代码以使用overload of AddEntry() that accepts a WriteDelegate。它是专门为将数据集添加到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);
}这会将数据集直接写入zipfile中的压缩流中。非常高效!没有双缓冲。匿名委托在ZipFile.Save()时被调用。仅执行一次写入(+压缩)。
发布于 2010-02-15 22:13:15
你有没有试过在拉链之前冲掉小溪?
dt.WriteXml(stream);
stream.Flush();
ZipFile zipFile = new ZipFile();发布于 2010-02-15 23:12:24
好的。看起来我们还没有走到这一步,所以你需要多调试一下。
更新您的代码以执行以下操作:
dt.WriteXml(stream);
stream.Seek(0, SeekOrigin.Begin);
File.WriteAllBytes("c:\test.xml", stream.GetBuffer());看看您是否有一个有效的XML文件。如果你这样做了,那么继续对你的ZipFile做同样的事情。将其保存到本地文件。看看它是否在那里,是否有您的xml文件和xml文件中的内容。
如果这样做有效,试着只发送回内存流作为响应,看看是否有效。
然后,您应该能够进一步跟踪问题。
https://stackoverflow.com/questions/2266204
复制相似问题