Did you know – Zip is built into .NET?

food-cof-01 A couple of weeks ago, I was working on a project that required me to unzip a file.  There is only one text file in the zip, so using a full-blown library like SharpZipLib (OpenSource) or some commercial product just didn’t seem right.  From my experience with Java, I knew zip routines were available as part of the Java libraries in .NET (JSharp).  It seemed like my best bet would be to use what was already available rather than having yet another DLL on my system.

The two classes you will need from the JSharp libray are ZipFile and ZipEntry.  These are both located in the java.util.zip namespace.  You will need to add a reference to the vjslib assembly too.

To load the file from your drive, use:

ZipFile zf = new ZipFile(FileName);

To get the entires out of the zip file, use:

ZipEntry ze = (ZipEntry)(zf.entries().nextElement());

If you had multiple entries in your zip file, you’d need to put that in a loop of course.  But since my zip file only has one entry, that is all the code I need to get that entry.

The rest of the code is simply pulling the data out of the stream.

InputStreamProxy isp =
    new InputStreamProxy(zf.getInputStream(ze));

We will take a look at the InputStreamProxy class later on, but for now all you need to know is that it converts the Java InputStream that getInputStream() returns into a .NET InputStream so that the rest of our code can use it.  This is the one place where I think Microsoft could have helped us out a bit.  Every Java to .NET port involving streams has this code or something very similar in it.

byte[] content = new byte[1024];
StringBuilder sb = new StringBuilder();
int cnt = 0;
while ((cnt = isp.Read(content, 0, 1024)) > 0)
{

    string str;
    System.Text.ASCIIEncoding enc =
        new System.Text.ASCIIEncoding();
    str = enc.GetString(content);
    str = str.Substring(0, cnt);
    sb.Append(str);
}

This is just your basic “read bytes from a stream” code.  Since we want to use the data as plain text, we need to use the ASCIIEncoding() method to convert the bytes to a string.  You’ll notice that I’m also using a StringBuilder to build up my string efficiently.

So the only thing left to show is the InputStreamProxy class.  There really isn’t a whole lot to show since all it does is wrap the java.io.InputStream class that the getInputStream method returns.

class InputStreamProxy : Stream
{
    private java.io.InputStream istrm;

    public InputStreamProxy(java.io.InputStream istrm)
    {
        this.istrm = istrm;
    }

    /** @property */
    public java.io.InputStream get_JavaStream()
    {
        return istrm;
    }

    /** @property */
    public override bool CanRead
    {
        get
        {
            return true;
        }
    }

    /** @property */
    public override bool CanSeek
    {
        get
        {
            return false;
        }
    }

    /** @property */
    public override bool CanWrite
    {
        get
        {
            return false;
        }
    }

    /** @property */
    public override long Length
    {
        get
        {
            throw new System.NotSupportedException();
        }
    }

    /** @property */
    public override long Position
    {
        get
        {
            throw new System.NotSupportedException();
        }
        set
        {
            throw new System.NotSupportedException();
        }
    }

    public override void Flush()
    {
        //do nothing
    }

    public override int Read(byte[] buffer,
        int offset, int count)
    {

        int readBytes;
        try
        {
            readBytes =
                istrm.read((sbyte[])((object)buffer),
                offset, count);
        }
        catch (java.io.IOException ioe)
        {
            throw new System.IO.IOException(ioe.Message);
        }
        return readBytes;
    }

    public override long Seek(long offset,
        SeekOrigin origin)
    {
        throw new System.NotSupportedException();
    }

    public override void SetLength(long value)
    {
        throw new System.NotSupportedException();
    }

    public override void Write(byte[] buffer,
        int offset, int count)
    {
        throw new System.NotSupportedException();
    }

    public override void Close()
    {
        try
        {
            istrm.close();
        }
        catch (java.io.IOException ioe)
        {
            throw new
                System.ObjectDisposedException(
                    ioe.getMessage());
        }
    }
}

You’ll see that the bulk of the code is in the Read method which simply calls the Read method of the Java stream.

 

Other post in Did you know

Related Post

One Response to “Did you know – Zip is built into .NET?”

  • James:

    Actually, it’s not built into the .NET Framework. It’s built into the J# Runtime Package… and J# is a separate install that runs on top of .NET 2.0 or newer.

    So you have yet-another-DLL, except in this case, you have the baggage of the full J# runtime instead of just a small DLL… and you have the added hassle of deploying J# with your app rather than just dropping in one more DLL into your app’s existing deployment.

Leave a Reply

Comment Policy:

  • You must verify your comment by responding to the automated email that is sent to your email address. Unverified comments will never show.Leave a good comment that adds to the conversation and I'll leave your link in.
  • Leave me pure spam and I'll delete it.
  • Leave a general comment and I'll remove the link but keep the comment.

Notify me of followup comments via e-mail

Bear