8

I have a zipped file having size of several GBs, I want to get the size of Unzipped contents but don't want to actually unzip the file in C#, What might be the Library I can use? When I right click on the .gz file and go to Properties then under the Archive Tab there is a property name TotalLength which is showing this value. But I want to get it Programmatically using C#.. Any idea?

Muhammad Ummar
  • 3,541
  • 6
  • 40
  • 71

4 Answers4

12

The last 4 bytes of the gz file contains the length.

So it should be something like:

using(var fs = File.OpenRead(path))
{
  fs.Position = fs.Length - 4;
  var b = new byte[4];
  fs.Read(b, 0, 4);
  uint length = BitConverter.ToUInt32(b, 0);
  Console.WriteLine(length);
}
johnnyRose
  • 7,310
  • 17
  • 40
  • 61
leppie
  • 115,091
  • 17
  • 196
  • 297
4

The last for bytes of a .gz file are the uncompressed input size modulo 2^32. If your uncompressed file isn't larger than 4GB, just read the last 4 bytes of the file. If you have a larger file, I'm not sure that it's possible to get without uncompressing the stream.

Gabe
  • 84,912
  • 12
  • 139
  • 238
2

EDIT: See the answers by Leppie and Gabe; the only reason I'm keeping this (rather than deleting it) is that it may be necessary if you suspect the length is > 4GB


For gzip, that data doesn't seem to be directly available - I've looked at GZipStream and the SharpZipLib equivalent - neither works. The best I can suggest is to run it locally:

    long length = 0;
    using(var fs = File.OpenRead(path))
    using (var gzip = new GZipStream(fs, CompressionMode.Decompress)) {
        var buffer = new byte[10240];
        int count;
        while ((count = gzip.Read(buffer, 0, buffer.Length)) > 0) {
            length += count;
        }
    }

If it was a zip, then SharpZipLib:

    long size = 0;
    using(var zip = new ZipFile(path)) {
        foreach (ZipEntry entry in zip) {
            size += entry.Size;
        }
    }
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • Thanks Marc, the first method worked for me.. but its taking too long to calculate a 2 GB uncompressed file... and it should be as we are counting in loop... Isn't there any quick way? – Muhammad Ummar Jan 12 '11 at 07:40
  • @Ummar: Both Gabe and myself explained the 'correct' way of doing this. The above way will work, but imagine using it on 1000's of 2GB files, it will take forever. – leppie Jan 12 '11 at 07:46
-2
public static long mGetFileLength(string strFilePath)
{
    if (!string.IsNullOrEmpty(strFilePath))
    {
        System.IO.FileInfo info = new System.IO.FileInfo(strFilePath);
        return info.Length;
    }

    return 0; 
}
Tim Stone
  • 19,119
  • 6
  • 56
  • 66