5

I'm using SharpZipLib to unzip files. My code has been working nicely for all zipfiles except the zip file what i am extracting now...

Got this exception:

System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
Parameter name: length

The exception is being thrown at size = s.Read(data, 0, data.Length);

Hereb is my code...

 public static void UnzipFile(string sourcePath, string targetDirectory)
     {
        try
        {
            using (ZipInputStream s = new ZipInputStream(File.OpenRead(sourcePath)))
            {
                ZipEntry theEntry;
                while ((theEntry = s.GetNextEntry()) != null)
                {
                    //string directoryName = Path.GetDirectoryName(theEntry.Name);
                    string fileName = Path.GetFileName(theEntry.Name);

                    if (targetDirectory.Length > 0)
                    {
                        Directory.CreateDirectory(targetDirectory);
                    }

                    if (fileName != String.Empty)
                    {
                        using (FileStream streamWriter = File.Create(targetDirectory + fileName))
                        {
                            int size = 2048;
                            byte[] data = new byte[2048];
                            while (true)
                            {
                                size = s.Read(data, 0, data.Length);
                                if (size > 0)
                                {
                                    streamWriter.Write(data, 0, size);
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
        catch (Exception ex)
        {
            throw new Exception("Error unzipping file \"" + sourcePath + "\"", ex);
        }
    }
bala3569
  • 10,832
  • 28
  • 102
  • 146
  • I've just tried your example and its working fine for me. Either the problem with zip package or with version of library. I used 'v1.1.4322' – Andrey Tagaew Dec 14 '10 at 07:21
  • @Andrey: There's no such version of SharpZipLib - the latest is 0.86. I think you're getting confused with the longer version number for .NET 1.1. – Jon Skeet Dec 14 '10 at 07:38
  • Ah, right, it was runtime version property value. Sorry. The library is of version 0.84 – Andrey Tagaew Dec 14 '10 at 07:53

3 Answers3

5

Looks like a bug to me. Fortunately, you have access to the code, so you should be able to see exactly where it's going wrong. I suggest you build a debug version of SharpZipLib, break on the line which is throwing the exception, and have a look at what it's actually testing.

It should be fine to read into a 2K buffer even if there's not 2K of data left.

(I wouldn't actually write the code quite how you have, but that's a different matter. I'd also move it into its own utility method - the act of copying all the data from one stream to another is pretty common. There's no need to tie it to zip.)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
-1

Looking at the code, you are reading the same set of bytes again (and advancing the position).

size = s.Read(data, 0, data.Length);

An example from here shows that the 2nd argument should be a moving position & not a fixed number.

shahkalpesh
  • 33,172
  • 3
  • 63
  • 88
  • @shahkalpesh: No, it's reading different data, but into the same buffer again and again... which is fine, as the OP is then *writing out* the buffer to another stream. It's fine. – Jon Skeet Dec 14 '10 at 07:07
  • @Jon: So, the example on the link is incorrect? Please note that the documentation is of `System.IO.Stream` and not `ZipInputStream`. – shahkalpesh Dec 14 '10 at 07:25
  • @shahkalpesh: It's correct for what it's trying to do, which isn't the same as what the OP is trying to do. – Jon Skeet Dec 14 '10 at 07:29
  • @Jon: Could you please explain, what is OP doing different from what the link explains? If I understand correctly, OP's code is reading from a stream in the chunks of 2048 bytes, which is somewhat similar to what the code from the link does. – shahkalpesh Dec 14 '10 at 08:07
  • @shahkalpesh: On each iteration, he's then writing out the data to another stream... so he doesn't need the data in the buffer after that. This is a very common way of copying the contents of one stream to another. It's fine. The code in the documentation is trying to copy the *whole* contents of a stream into a byte array - so all of the data is in memory at a time. The OP doesn't want or need to do that. – Jon Skeet Dec 14 '10 at 08:11
-1

Change your code int size = 2048; to int size = data.Length;. You won't take OutOfRange exception.

 using (FileStream streamWriter = File.Create(targetDirectory + fileName))
    {
       int size = data.Length;
       byte[] data = new byte[size];
       while (true)
       {
            size = s.Read(data, 0, data.Length);
            if (size > 0)
            {
                streamWriter.Write(data, 0, size);
            }
            else
            {
               break;
            }
       }
    }
maycil
  • 754
  • 2
  • 8
  • 24
  • You're trying to use a variable before it's been declared (`size`). Admittedly in the original code, the initial value of `size` wasn't even being used... but changing it to a different initial value isn't going to help. – Jon Skeet Dec 14 '10 at 07:30