I am using MemoryStream and the ICSharpZipLib to write data from a dataset into a zip file in memory and then sending the result to the client so the user can save the file locally.
This is working fine with smaller datasets but is tanking when the dataset gets to somewhere between 100K and 180K bytes in the buffer. When they get to this size, I get a Thread was being aborted error and the zip file is corrupted and will not open.
Is there anything I can do to allow larger amounts of data to be written into memory or do I need to just start writing the file our to disk using Streamwriter? The code is below.
Thanks.
MonkeyZ
// get the name of the zip file
string strFileName = Request.Params["report"];
// Clear out any html we may be sending, set the headers for sending a zipfile
Response.ClearContent();
Response.ContentType = "application/x-zip-compressed";
Response.AddHeader("Content-Disposition", "attachment; filename=\"" + strFileName + ".zip\"");
// Create a memorystream instead of a file to hold the zip file as it is built
MemoryStream mStrm = new MemoryStream();
ZipOutputStream zOut = new ZipOutputStream(mStrm);
// Compression ratio -- 0 = store only to 9 = means best compression
zOut.SetLevel(5);
// For each table in our dataset
foreach (DataTable dt in ds.Tables)
{
// Start a new string for the tsv data, use a stringbuilder for speed
StringBuilder dataString = new StringBuilder();
#region Build the TSV header row
foreach ( DataColumn col in dt.Columns) {
dataString.Append(col.ColumnName.Replace(",",".") + "\t");
}
dataString.Remove(dataString.Length-1,1); // Chop the last comma from the above loop;
dataString.Append("\r\n"); // return linefeed.
#endregion
#region Build TSV rows for each row in the table
foreach (DataRow row in dt.Rows) {
foreach (object val in row.ItemArray){
if (val != null)
// Make sure you remove all commas in the data to avoid breaking a CSV set
dataString.Append(val.ToString().Replace(",",".") + "\t");
else
// No Data ... Empty value
dataString.Append("\t");
}
dataString.Remove(dataString.Length-1,1); // Chop the last comma from the above loop;
dataString.Append("\r\n"); // return linefeed.
}
#endregion
#region Create a Zip file file header
// Name the file in the archive using the table_name.csv
ZipEntry zEnt = new ZipEntry(strFileName + ".txt");
// File creation date ... how about right now? :)
zEnt.DateTime = DateTime.Now;
zEnt.Size = dataString.Length;
// Place the file entry in the zip file stream
zOut.PutNextEntry(zEnt);
#endregion
// Convert from StringBuilder -> String -> Byte[ and dump to our memory string
zOut.Write(System.Text.Encoding.ASCII.GetBytes(dataString.ToString()),0,dataString.Length);
}
// Let the Zip Stream do it's work
zOut.Finish();
// Dump the Zip file in memory to the response stream
Response.BinaryWrite(mStrm.GetBuffer());
zOut.Close();
// Clean up and get outta here
Response.Flush();
Response.End();