2012-06-06 9 views
5

que actualmente tiene el siguiente código que se lee un archivo que se encuentra en la web y lo escribe en un archivo en el teléfono:¿Se puede determinar el tamaño del archivo que se descargará?

InputStream inputStream = new URL(sourceFileWebAddress).openStream(); 
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream); 
FileOutputStream fileOutputStream = new FileOutputStream(targetFile); 

int count; 
byte buffer[] = new byte[1024]; 

while ((count = bufferedInputStream.read(buffer, 0, buffer.length)) != -1) 
    fileOutputStream.write(buffer, 0, count); 

¿Alguien sabe si es posible (utilizando la configuración anterior o de otro modo) para determinar el número total de bytes que se deben leer antes de comenzar con la descarga (para publicar el progreso porcentual al usuario a medida que avanza la descarga)?

Respuesta

6

utiliza el método de URLConnection

URL url = new URL(sourceFileWebAddress); 
URLConnection connection = url.openConnection(); 
connection.connect(); 

int fileLenth = connection.getContentLength(); 

InputStream inputStream = url.openStream(); 
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream); 
+4

También la longitud del contenido puede ser -1 si el servidor no es compatible con esto o por alguna razón el tamaño del archivo es desconocido. –

+0

ADVERTENCIA: 'url.openConnection(). GetContentLength()' hará un 'GET' y no un' HEAD'. Consulte la respuesta de Santosh a continuación para obtener un mejor método (es decir, haga 'connection.setRequestMethod (" HEAD ")' antes de llamar a 'getContentLength()'). –

2

Puede enviar una solicitud al servidor para devolver el tamaño del archivo. Use ese tamaño de archivo en su barra de progreso e inicie la descarga. Por lo tanto, estas son dos solicitudes separadas, pero puede agruparlas en la misma tarea asyc. Así que primero obtienes el campo, realiza una llamada al progressUpdate donde configuras los valores para la barra de progreso y luego continúas con la descarga con llamadas periódicas al progressUpdate() para cambiar el estado de la barra de progreso.

3

getContentLength probar esto usando URLConnnection

URLConnection connection = new URL(sourceFileWebAddress).openStream(); 
InputStream stream = connection.getInputStream(); 

System.out.println("total size: "+connection.getContentLength();//size 

BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream); 
FileOutputStream fileOutputStream = new FileOutputStream(targetFile); 

int count; 
byte buffer[] = new byte[1024]; 

while ((count = bufferedInputStream.read(buffer, 0, buffer.length)) != -1) 
    fileOutputStream.write(buffer, 0, count); 
1

El método de getContentLengthURLConnection debe darle el tamaño del archivo a descargar. A partir de esto, puede dibujar su ProgressBar como lo desee, actualizándola (en ongressUpdate, suponiendo que está haciendo esto dentro de AsyncTask, lo está, ¿no?) Cada vez que su fileOutputStream procesa datos nuevos.

Si el servidor no le da un valor en getContentLength (-1 en la mayoría de los casos, pero al menos compruebe si es menor o igual que cero), simplemente haga que su ProgressBar sea indeterminado.

3

para determinar el número total de bytes que se van a leer antes que comienza con la descarga, una forma es sólo recibe las cabeceras de respuesta mediante el envío de una solicitud HTTP CABEZA de la siguiente manera:

import java.io.IOException; 
import java.net.HttpURLConnection; 
import java.net.MalformedURLException; 
import java.net.ProtocolException; 
import java.net.URL; 

public class SimpleHTTPRequest { 

    public static void main(String[] args) { 
     HttpURLConnection connection = null; 
     URL serverAddress = null; 

     try { 
      String sourceFileWebAddress = "http://localhost:8080/mycontents"; 
      serverAddress = new URL(sourceFileWebAddress); 
      //set up out communications stuff 
      connection = null; 

      //Set up the initial connection 
      connection = (HttpURLConnection)serverAddress.openConnection(); 

      //HEAD request will make sure that the contents are not downloaded. 
      connection.setRequestMethod("HEAD"); 

      connection.connect(); 
      System.out.println("========"+connection.getContentLength()); 

     } catch (MalformedURLException e) { 
      e.printStackTrace(); 
     } catch (ProtocolException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     finally 
     { 
      //close the connection, set all objects to null 
      connection.disconnect(); 

      connection = null; 
     } 
    } 
} 

Esto imprimirá el tamaño del contenido que se descargará sin descargar realmente los contenidos.

+0

La documentación del método 'URLConnection.getContentLength()' (según lo sugerido por los otros contestadores) dice: "Devuelve la longitud del contenido en bytes especificada por el campo del encabezado de respuesta' content-length' o -1 si este campo no está establecido " Entonces parece que este método de hecho tampoco descarga los contenidos. Corrígeme si estoy equivocado. –

+1

Adil, sí, eso es correcto. Recibe solo encabezados sin activar la descarga del archivo. – Santosh

+0

No, 'url.openConnection(). GetContentLength()' hará un 'GET' (por lo menos en Java 7). Configure un servidor y revise las solicitudes que envía un cliente Java. –

Cuestiones relacionadas