gpt4 book ai didi

c# - 从流创建 Zip 文件并下载

转载 作者:IT王子 更新时间:2023-10-29 03:53:13 25 4
gpt4 key购买 nike

我有一个 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 examples 中所述。 ,代替调用 Dispose()。 using() 子句在遇到故障时更可靠。

Now you may wonder, why is it necessary to seek in the MemoryStream before calling AddEntry()? The reason is, AddEntry() is designed to support those callers who pass a stream where the position is important. In that case, the caller needs the entry data to be read from the stream, using the current position of the stream. AddEntry() supports that. Therefore, set the position in the stream before calling 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);
}

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

关于c# - 从流创建 Zip 文件并下载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2266204/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com