views:

369

answers:

4

I grabbed the following code somewhere off the net, and I am using it to decompress Gzip files, such as http://wwwmaster.postgresql.org/download/mirrors-ftp/pgadmin3/release/v1.8.4/src/pgadmin3-1.8.4.tar.gz but when I run It, I get an exception, stating that the magic number doesnt match.

public byte[] Download(string pUrl) {
  WebClient wc = new WebClient();
  byte[] bytes = wc.DownloadData(pUrl);
  return UnGzip(bytes, 0);
}

private static byte[] UnGzip(byte[] data, int start) {
  int size = BitConverter.ToInt32(data, data.Length - 4);
  byte[] uncompressedData = new byte[size];
  MemoryStream memStream = new MemoryStream(data, start, (data.Length - start));
  memStream.Position = 0;
  GZipStream gzStream = new GZipStream(memStream, CompressionMode.Decompress);

  try {
    gzStream.Read(uncompressedData, 0, size);
  } catch (Exception gzError) {
    throw;
  }

  gzStream.Close();
  return uncompressedData;
}

Can anyone help as to whats wrong with the code that would cause this problem?

+1  A: 

I couldn't get the GZipStream to read the file you linked, but it seems to decompress other GZip files just fine. For example:

ftp://gnu.mirror.iweb.com/gnu/bash/bash-1.14.0-1.14.1.diff.gz

ftp://gnu.mirror.iweb.com/gnu/emacs/elisp-manual-21-2.8.tar.gz

Perhaps the file you linked is corrupt? Or maybe it uses a non-standard or new GZip format.

Jim Mischel
A: 

.NET does not support tar format. GZip is simply a byte compressor. Tar is the container format.

Formats like Zip and RAR, combines both these steps for you, but they are not good for streaming compression.

IIRC SharpZipLib has support for tar.

leppie
A: 

I've used DotNetZip with some success with .zip files. According to the docs it also works with GZip. You might give this guy's library a try.

CodeMonkeyKing
DotNetZip does GZIP, just the same way that the built-in GZipStream class does. Using DotNetZip wouldn't actually change the code offered by the OP, except for the namespaces. The main benefit to using DotNetZip is that it is more effective in compression. No advantage in decompression.
Cheeso
+3  A: 

The problem is that the URL you specified in your question doesn't actually give a gzip file. It takes the browser to a page where you select a mirror.

If you temporarily change your Download method to use:

string text = wc.DownloadString(pUrl);
Console.WriteLine(text);

you'll see all the HTML for mirror selection.

If you use a URL which is the actual gz file, e.g. http://wwwmaster.postgresql.org/redir/170/h/pgadmin3/release/v1.8.4/src/pgadmin3-1.8.4.tar.gz then it works fine.

Jon Skeet