2012-08-25 25 views
5

Ho scaricato alcuni file nella mia app java e ho implementato una finestra di dialogo per il monitoraggio del download. Ma recentemente ho compresso tutti i file con gzip e ora il monitor di download è un po 'rotto.Monitoraggio GZip Download avanzamento in Java

Apro il file come GZIPInputStream e aggiorno lo stato del download dopo ogni kB scaricato. Se il file ha una dimensione di 1 MB, il progresso salirà a es. 4 MB che è la dimensione non compressa. Voglio monitorare i progressi del download compresso. È possibile?

MODIFICA: per chiarire: sto leggendo i byte dal GZipInputStream che sono i byte non compressi. Quindi questo non mi dà la giusta dimensione di file alla fine.

Ecco il mio codice:

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

Grazie per qualsiasi aiuto!

+0

Sto leggendo i byte scaricati dal 'GZipInputStream' che è il flusso non compresso. Quindi questa non è la dimensione reale che viene scaricata. – dbrettschneider

+0

Ok, ora lo vedo. – SJuan76

risposta

4

Secondo le specifiche, GZIPInputStream è una sottoclasse di InflaterInputStream. InflaterInputStream ha un campo protected Inflater inf che è il Inflater utilizzato per il lavoro di decompressione. Inflater.getBytesRead dovrebbe essere particolarmente utile per i tuoi scopi.

Sfortunatamente, GZIPInputStream non espone inf, quindi probabilmente sarà necessario creare una propria sottoclasse ed esporre lo Inflater, ad es.

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

Grazie! Ho appena dovuto implementare un GZIPInputStream personalizzato che rende disponibile 'getBytesRead()' di Inflater int'. – dbrettschneider

+0

Grazie, questo è esattamente quello che stavo cercando! –