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

  • iText IN ACTION – Creating and Manipulating PDFiText IN ACTION – Creating and Manipulating PDF While this isn’t specifically targeted at iTextSharp, which we’ve been covering in recent posts, this is really the closest book you are going to find on the subject. The basics are the same.&#...
  • Reflection -The ConstructorReflection -The Constructor Remember, last week we started a series on using Reflection in our .NET applications.  We've loaded the assembly already, so the next step is creating the object.  Today's tutorial will show how to...
  • Native Client: Been There, Done ThatNative Client: Been There, Done That Google Code Blog: Native Client: A Technology for Running Native Code on the Web At Google we're always trying to make the web a better platform. That's why we're working on Native Client, a tech...
  • Reflection – Loading The AssemblyReflection – Loading The Assembly Recently, I received a question from a web visitor asking me to cover reflection.  So, I'm going to start a series on reflection.  Remember, if you have any questions you can ask me using...
  • Which Language VB or CSharp?Which Language VB or CSharp? I wrote the following article a long time ago on my main domain, but recently I had a reader send in a question that this article addresses.  So I’m putting this article here so that it is easier f...
  • 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.