Question

I do not seem to be able to write text via StreamWriter to a to be newly created zip file (not gzip). I use SharpZipLib and do not quite comprehend how to get it to work. DJ Kraze helped me with streaming content from a zipped text file to StreamReader, I now try the opposite. I do not want to create a csv file first and then compress the finalized file but like to stream text directly to a to be created csv within the zip container. Is that possible? Below a snippet I use for getting a stream that I can use with StreamReader, it just gives an idea what I am looking for, just that this time I like to get a stream to be used with StreamWriter.

public static Stream GetZipInputFileStream(string fileName)
{
    ZipInputStream zip = new ZipInputStream(File.OpenRead(fileName));
    FileStream filestream = 
        new FileStream(fileName, FileMode.Open, FileAccess.Read);
    ZipFile zipfile = new ZipFile(filestream);
    ZipEntry item;

    if ((item = zip.GetNextEntry()) != null)
    {
        return zipfile.GetInputStream(item);
    }
    else
    {
        return null;
    }
}

Here is how I use it, which I essentially look for but the other way around (StreamWriter -> new csv file in new zip container):

using (StreamReader streamReader = Path.GetExtension(fileName).ToUpper().Equals(".ZIP") ? new StreamReader(FileOperations.GetZipInputFileStream(fileName)) : new StreamReader(fileName))
            {
Was it helpful?

Solution 2

I ended up dumping SharpZipLib for this purpose and instead went the more space intensive route of first unzipping all files in the zip container, processing the data and then moving the files back into the zip container. The problem I faced, as described above was that I could not read any of the files in the container at once due to their large size. It would be nice to see a zip library that may be able to handle partial stream writing into the container in the future but for now I did not see a way to get it done with SharpZipLib.

OTHER TIPS

The second example here addresses writing a stream directly to a zip file from SharpZipLib. Give that a quick look and let us know how it works for you.

Edit: Since the link is being problematic, below is the example from the wiki.

public void UpdateZipInMemory(Stream zipStream, Stream entryStream, String entryName) 
{

    // The zipStream is expected to contain the complete zipfile to be updated
    ZipFile zipFile = new ZipFile(zipStream);

    zipFile.BeginUpdate();

    // To use the entryStream as a file to be added to the zip,
    // we need to put it into an implementation of IStaticDataSource.
    CustomStaticDataSource sds = new CustomStaticDataSource();
    sds.SetStream(entryStream);

    // If an entry of the same name already exists, it will be overwritten; otherwise added.
    zipFile.Add(sds, entryName);

    // Both CommitUpdate and Close must be called.
    zipFile.CommitUpdate();

    // Set this so that Close does not close the memorystream
    zipFile.IsStreamOwner = false;
    zipFile.Close();

    // Reposition to the start for the convenience of the caller.
    zipStream.Position = 0;
}

And the supporting data structure

public class CustomStaticDataSource : IStaticDataSource
{
    private Stream _stream;

    // Implement method from IStaticDataSource
    public Stream GetSource() { return _stream; }

    // Call this to provide the memorystream
    public void SetStream(Stream inputStream) 
    {
        _stream = inputStream;
        _stream.Position = 0;
    }
}

There's an example of calling that code if you can get through to the site.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top