2 вещи. Во-первых, если вы сохраняете дизайн кода, который вам нужен, вам нужно выполнить Seek () для MemoryStream перед записью его в запись.
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 вместо вызова Dispose (). Предложение using () более надежно в случае сбоев.
Теперь вы можете задаться вопросом, зачем искать в MemoryStream перед вызовом AddEntry ()? Причина в том, что AddEntry () предназначен для поддержки тех вызывающих абонентов, которые передают поток, где важна позиция. В этом случае вызывающей стороне необходимо, чтобы входные данные были прочитаны из потока, , используя текущую позицию потока . AddEntry () поддерживает это. Поэтому установите позицию в потоке перед вызовом AddEntry ().
Но лучший вариант - изменить код для использования перегрузки метода AddEntry (), который принимает 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-файле. Очень эффективный! Нет двойной буферизации. Анонимный делегат вызывается во время ZipFile.Save (). Выполняется только одна запись (+ сжатие).