2011-01-12 11 views
8

Mam spakowany plik o rozmiarze kilku GB, chcę uzyskać rozmiar rozpakowanej zawartości, ale nie chcę rozpakować pliku w C#, co może być biblioteką, której mogę użyć ? Po kliknięciu prawym przyciskiem myszy na pliku .gz i przejściu do Właściwości następnie pod zakładką Archive znajduje się nazwa właściwości TotalLength, która pokazuje tę wartość. Ale chcę uzyskać to programowo przy użyciu C# .. Jakiś pomysł?Plik GZIP Całkowita długość w C#

+0

Informacja może być obecna w nagłówku programu gzip. Ale nie mogę pomóc więcej. – leppie

Odpowiedz

8

Ostatnie 4 bajty pliku gz zawiera długość.

Tak powinno być coś takiego:

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); 
} 
+1

ah, znacznie lepiej; Nie wiem, jak to się dzieje, gdy> 4GB choć –

+0

Dzięki Leppie ... faktycznie w moim przypadku plik będzie mniejszy niż 4 GB ... Dziękujemy za pomoc ... –

+0

@johnnyrose: Dzięki za korektę literówki: D – leppie

-1
public static long mGetFileLength(string strFilePath) 
{ 
    if (!string.IsNullOrEmpty(strFilePath)) 
    { 
     System.IO.FileInfo info = new System.IO.FileInfo(strFilePath); 
     return info.Length; 
    } 

    return 0; 
} 
2

EDYCJA: Zobacz odpowiedzi autorstwa Leppie i Gabe; jedynym powodem Trzymam to (a nie usuwając go) jest to, że może to być konieczne, jeśli podejrzewasz, że długość jest> 4GB


Dla gzip, że dane nie wydaje się być bezpośrednio dostępne - ja "Patrzyłem na GZipStream i odpowiednik SharpZipLib - nie działa. Najlepsze, co mogę zasugerować to, aby go uruchomić lokalnie:

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; 
     } 
    } 

Jeśli to był błyskawiczny, następnie SharpZipLib:

long size = 0; 
    using(var zip = new ZipFile(path)) { 
     foreach (ZipEntry entry in zip) { 
      size += entry.Size; 
     } 
    } 
+0

Dzięki Marc, pierwsza metoda zadziałała dla mnie ... ale jej zajęcie trwa zbyt długo, aby obliczyć plik bez kompresji o pojemności 2 GB ... i powinno być tak, jak liczymy w pętli ... Czy nie ma szybkiej metody? –

+0

@Ummar: Zarówno Gabe, jak i ja wyjaśniliśmy "poprawny" sposób robienia tego. Powyższy sposób zadziała, ale wyobraź sobie, że używając go na tysiącach plików 2GB, zajmie to całe wieki. – leppie

+0

@Ummar - patrz odpowiedź @ leppiego –

4

Ostatnim dla bajtów pliku .gz są wielkości Modulo wejściowy nieskompresowany 2^32. Jeśli nieskompresowany plik nie jest większy niż 4 GB, po prostu przeczytaj ostatnie 4 bajty pliku. Jeśli masz większy plik, nie jestem pewien, czy można go uzyskać bez dekompresji strumienia.