2012-08-25 28 views
5

Descargo algunos archivos en mi aplicación Java e implemento un diálogo de monitor de descarga. Pero recientemente comprimí todos los archivos con gzip y ahora el monitor de descarga está algo roto.Monitorear progreso de descarga de GZip en Java

Abrí el archivo como GZIPInputStream y actualicé el estado de descarga después de descargar cada kB. Si el archivo tiene un tamaño de 1 MB, el progreso sube hasta, p. 4MB que es el tamaño sin comprimir. Quiero monitorear el progreso de la descarga comprimida. es posible?

EDITAR: Para aclarar: Estoy leyendo los bytes de GZipInputStream que son los bytes sin comprimir. Entonces eso no me da el tamaño correcto del archivo al final.

Aquí está mi código:

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

Gracias por cualquier ayuda!

+0

Estoy leyendo los bytes descargados por el 'GZipInputStream' que es el flujo sin comprimir. Entonces este no es el tamaño del archivo real que se descarga. – dbrettschneider

+0

Ok, ahora lo veo. – SJuan76

Respuesta

4

De acuerdo con la especificación, GZIPInputStream es una subclase de InflaterInputStream. InflaterInputStream tiene un campo protected Inflater inf que es el Inflater utilizado para el trabajo de descompresión. Inflater.getBytesRead debe ser particularmente útil para sus propósitos.

Desafortunadamente, GZIPInputStream no expone inf, así que probablemente usted tendrá que crear su propia subclase y exponer la Inflater, por ejemplo,

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

Gracias! Solo tuve que implementar un GZIPInputStream personalizado que hace que 'getBytesRead()' del 'Inflater int' esté disponible. – dbrettschneider

+0

¡Gracias, esto es exactamente lo que estaba buscando! –

Cuestiones relacionadas