ZlibStream output file.

Oct 23, 2009 at 9:31 PM

I really hate to ask this, but I cannot find the answer from searching. When using ZlibStream to create a .zip file (actually appears in Windows as a zip folder), the file cannot be opened directly by Windows when one clicks on the file. What I want to do is continue to stream log information for hours to a zip file log. I want to then be able to open that file using Windows Explorer. Is this at all possible with DotNetZip?

Thank you for your help and I am sorry if this question has been answered else where.

Coordinator
Oct 23, 2009 at 10:55 PM
Edited Oct 23, 2009 at 11:10 PM
ChrisO wrote:

I really hate to ask this, but I cannot find the answer from searching. When using ZlibStream to create a .zip file (actually appears in Windows as a zip folder), the file cannot be opened directly by Windows when one clicks on the file.

Hello Chris!  no problem on the questions.

You cannot produce a .ZIP file using ZlibStream, not without a lot of work.  ZlibStream produces a zlib-compressed stream of data, or consumes a zlib-compressed stream of data. It's not the same thing as a zip file.  That explains why Windows cannot open it when you click on it.

ChrisO wrote:

What I want to do is continue to stream log information for hours to a zip file log. I want to then be able to open that file using Windows Explorer. Is this at all possible with DotNetZip?

If you want to produce a zip file, you need to use the ZipFile class, or the ZipOutputStream class.  The ZipOutputStream is new for DotNetZip v1.9. 

If using the ZipFile class, I would use a WriteDelegate, like this:

// this method gets invoked during zip.Save()
private void WriteEntry (String filename, Stream output)
{
    // Write the log data here. This can take hours...
    byte[] logdata= new byte[1000];
    bool done = false;
    while (!done)
    {
        // obtain data to log here
        int n = FillLogData(logdata);
        // stream it to the zip file here 
        output.Write(logdata, 0, n); 
        //  use some criteria to decide when we're done
        if (n == 0) done = true;        
    }
}

private void Run()
{
    string zipFileName = "ZippedLog.zip"; 
    string zipEntryName = "MyApplication.log";
    using (var zip = new ZipFile())
    {
        zip.AddEntry(zipEntryName, WriteEntry);
        zip.Save(zipFileName);
    }
}

If using the ZipOutputStream, I would suggest something like this:

string zipFileName = "AppLog.zip";
string zipEntryName = "MyApplication.log";
using (var raw = File.Open(zipFileName, FileMode.Create, FileAccess.ReadWrite ))
{
    using (var output= new ZipOutputStream(raw))
    {
        output.PutNextEntry(zipEntryName);
        // Write the log data here. This can take hours...
        byte[] logdata= new byte[1000];
        bool done = false;
        while (!done)
        {
            // obtain data to log here
            int n = FillLogData(logdata);
            // stream it to the zip file here 
            output.Write(logdata, 0, n); 
            //  use some criteria to decide when we're done
            if (n == 0) done = true;        
        }
    }
}
Oct 29, 2009 at 9:35 PM

Thank you very much. The ZipOutputStream looks like it will do what I require. I do have one other question though. I have many threads and each one is creating its own log file. My question now is if I have a separate stream and ZipOutputStream instance for each thread will the library code have any problems with that?

Thanks again. 

Coordinator
Oct 30, 2009 at 12:52 AM

No problem with multiple threads each doing their own zipping.  The ZipOutputStream class itself is NOT multithreaded, so you need to make sure at most one thread is calling into it at a time.  But if you have 5 threads and 5 ZipOutputStream instances, no problem.