Creating file without writing to disc...

May 7, 2009 at 12:40 AM
Hello,

I've tried searching for examples of how to do this, but haven't found them if they are already out there.

I'm trying to write a bit of code for a web-app (C#) that essentially takes a dataset and create a zip file.  The zip file should contain a csv file for each datatable in the dataset.  Each csv file should be relatively small in size and the file count could range from 2-10 files.  I can get each datatable into a csv format (either by string or stream).  From what I've read, it seems that DetNetZip should be able to handle this, but I'm clueless how to set this up.

My goal is to avoid writing anything to disc on the web-server and have the client's browser ask what to do with the zip-file that was just downloaded after an "Export" button was clicked.

Any insight would be greatly appriciated!

~ Ben
May 7, 2009 at 4:58 PM
Sorry to waste time here - a continual call of .AddFileFromString worked!

    private void ExportData(List<int> tables)
    {
        Response.Clear();
        Response.ContentType = "application/zip";
        Response.AddHeader("content-disposition", "filename=" + string.Format("archive-{0}.zip", DateTime.Now.ToString("yyyy-MMM-dd-HHmm")));

        using (ZipFile zip = new ZipFile())
        {
            foreach (int index in tables)
            {
                switch (index)
                {
                    case 1:
                        zip.AddFileFromString("blah-1.csv", "", ConvertTableToString(index));
                        break;
                    case 2:
                        zip.AddFileFromString("blah-2.csv", "", ConvertTableToString(index));
                        break;
                    case 3:
                        zip.AddFileFromString("blah-3.csv", "", ConvertTableToString(index));
                        break;
                }
            }
            zip.Save(Response.OutputStream);
        }
        
        Response.End();
    }

    private string ConvertTableToString(int datasetIndex)
    {
        // fun mapping code
    }
Coordinator
May 7, 2009 at 7:58 PM
Glad you found something that works for you.
There is also AddFileFromStream() which works similarly, but with a stream. a MemoryStream might be interesting in your scenario.
With this latter method you can provide the stream on a just-in-time basis. Check the docs if you are interested.

What you are doing will work just fine with a few entries in the zip, and a smallish zip file.  As zip files become larger and there are more files, the advantage of using just-in-time streams becomes real.  Imagine a zip file with 10,000 csv entries.  With AddFileFromString(), all that data has to be kept in memory.  With AddFileFromStream, you keep only the data for a single entry in memory at one time.

Thinking about it, I may be able to modify the library to provide the just-in-time capability with the AddFileFromString() method.  But no one has asked for that, yet.