2012-08-25 12 views
5

Ich lade einige Dateien in meiner Java App herunter und implementiere einen Download Monitor Dialog. Aber vor kurzem habe ich alle Dateien mit gzip komprimiert und jetzt ist der Download-Monitor irgendwie kaputt.Monitor GZip Download Fortschritt in Java

Ich öffne die Datei als GZIPInputStream und aktualisieren Sie den Download-Status nach jedem kB heruntergeladen. Wenn die Datei eine Größe von 1 MB hat, geht der Fortschritt z.B. 4MB, das ist die unkomprimierte Größe. Ich möchte den komprimierten Download-Fortschritt überwachen. Ist das möglich?

EDIT: Um zu verdeutlichen: Ich lese die Bytes aus dem GZipInputStream, die die unkomprimierten Bytes sind. Das gibt mir am Ende nicht die richtige Größe.

Hier ist mein Code:

URL url = new URL(urlString); 
HttpURLConnection con = (HttpURLConnection) url.openConnection(); 
con.connect(); 
... 
File file = new File("bibles/" + name + ".xml"); 
if(!file.exists()) 
    file.createNewFile(); 
out = new FileOutputStream(file); 
in = new BufferedInputStream(new GZIPInputStream(con.getInputStream())); 

byte[] buffer = new byte[1024]; 
int count; 
while((count = in.read(buffer)) != -1) { 
    out.write(buffer, 0, count); 
    downloaded += count; 
    this.stateChanged(); 
} 

... 

private void stateChanged() { 
    this.setChanged(); 
    this.notifyObservers(); 
} 

Vielen Dank für jede Hilfe!

+0

Ich lese die Bytes von der 'GZipInputStream' heruntergeladen, die der unkomprimierte Stream ist. Dies ist also nicht die tatsächliche Dateigröße, die heruntergeladen wird. – dbrettschneider

+0

Ok, jetzt sehe ich es. – SJuan76

Antwort

4

Gemäß der Spezifikation ist GZIPInputStream eine Unterklasse von InflaterInputStream. InflaterInputStream hat ein protected Inflater inf Feld, das ist die Inflater für die Dekompressionsarbeit verwendet. Inflater.getBytesRead sollte besonders nützlich für Ihre Zwecke sein.

Leider stellt GZIPInputStreaminf nicht frei, also müssen Sie wahrscheinlich Ihre eigene Unterklasse erstellen und die Inflater, z.

public final class ExposedGZIPInputStream extends GZIPInputStream { 

    public ExposedGZIPInputStream(final InputStream stream) { 
    super(stream); 
    } 

    public ExposedGZIPInputStream(final InputStream stream, final int n) { 
    super(stream, n); 
    } 

    public Inflater inflater() { 
    return super.inf; 
    } 
} 
... 
final ExposedGZIPInputStream gzip = new ExposedGZIPInputStream(...); 
... 
final Inflater inflater = gzip.inflater(); 
final long read = inflater.getBytesRead(); 
+0

Danke! Ich musste nur einen eigenen GZIPInputStream implementieren, der 'getBytesRead()' des 'Inflater int 'zur Verfügung stellt. – dbrettschneider

+0

Danke, das ist genau das, was ich gesucht habe! –