studio reales proyectos programacion libro introducción incluye herramientas fundamentos fuente español código con avanzado aplicaciones java http http-headers

reales - Java URLConnection: ¿cómo puedo averiguar el tamaño de un archivo web?



libro de android studio en español pdf (6)

Como se mencionó, el getContentLength de URLConnection es su mejor opción , pero no siempre dará una duración definida. Esto se debe a que el protocolo HTTP (y otros que podrían estar representados por una URLConnection) no siempre transmiten la longitud.

En el caso de HTTP, la longitud del contenido dinámico generalmente no se conoce de antemano, cuando normalmente se enviaría el encabezado de content-length del content-length . En cambio, otro encabezado, transfer-coding , especifica que se utiliza una codificación "fragmentada". Con la codificación fragmentada, la duración de toda la respuesta no se especifica, y la respuesta se envía de nuevo en pedazos, donde se especifica el tamaño de cada pieza. En la práctica, el servidor almacena la salida del servlet. Cada vez que el buffer se llena, se envía otro fragmento. Usando este mecanismo, HTTP podría comenzar a transmitir una respuesta de longitud infinita.

Otra razón por la que no podrá obtener la longitud de un archivo a través de URLConnection es si el archivo es más grande que 2 Gb, que es el límite para un entero positivo.

Estoy trabajando en un proyecto para la escuela y estoy implementando una herramienta que se puede usar para descargar archivos de la web (con una opción de aceleración). La cuestión es que tendré una GUI para ello y JProgressBar un widget JProgressBar , que me gustaría mostrar el progreso actual de la descarga. Para eso necesitaría saber el tamaño del archivo. ¿Cómo se obtiene el tamaño del archivo antes de descargar el archivo?


Querrá usar la longitud del contenido (URLConnection.getContentLength ()). Desafortunadamente, esto no siempre será preciso o no siempre se proporcionará, por lo que no siempre es seguro confiar en él.


Como dijo @erickson, a veces hay un encabezado "Transferir-Codificar: fragmentado", en lugar de "Contenido-Longitud:" y, por supuesto, tiene un valor nulo para la longitud.

Acerca del método available (): nadie puede garantizarle que devolverá el valor correcto, por lo que le recomiendo que no lo use.


Utilizando una solicitud HEAD, conseguí que mi servidor web respondiera con el campo de longitud de contenido correcto que de lo contrario estaba vacío. No sé si esto funciona en general, pero en mi caso sí lo hace:

private int tryGetFileSize(URL url) { HttpURLConnection conn = null; try { conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("HEAD"); conn.getInputStream(); return conn.getContentLength(); } catch (IOException e) { return -1; } finally { conn.disconnect(); } }


Se supone que cualquier respuesta HTTP debe contener un encabezado Content-Length, por lo que puede consultar el objeto URLConnection para este valor.

//once the connection has been opened List values = urlConnection.getHeaderFields().get("content-Length") if (values != null && !values.isEmpty()) { // getHeaderFields() returns a Map with key=(String) header // name, value = List of String values for that header field. // just use the first value here. String sLength = (String) values.get(0); if (sLength != null) { //parse the length into an integer... ... }

Puede que no siempre sea posible que un servidor devuelva una longitud de contenido precisa, por lo que el valor podría ser inexacto, pero al menos obtendría algún valor utilizable la mayor parte del tiempo.

actualización: O bien, ahora que miro el javadoc de URLConnection de manera más completa, puedes usar el método getContentLength () .


//URLConnection connection private int FileSize(String url) { // this is the method and it get the url as a parameter. // this java class will allow us to get the size of the file. URLConnection con; // its in a try and catch incase the url given is wrong or invalid try{ // we open the stream con = new URL(url).openConnection() return con.getContentLength(); }catch (Exception e){ e.printStackTrace(); // this is returned if the connection went invalid or failed. return 0; } }