internet from files example java github download binary urlconnection

from - java http download



Descargue el archivo binario de Github usando Java (5)

Estoy intentando descargar este archivo ( http://github.com/downloads/TheHolyWaffle/ChampionHelper/ChampionHelper-4.jar ) con el siguiente método y parece que no funciona. Obtengo un archivo vacío / corrupto.

String link = "http://github.com/downloads/TheHolyWaffle/ChampionHelper/ChampionHelper-4.jar"; String fileName = "ChampionHelper-4.jar"; URL url = new URL(link); URLConnection c = url.openConnection(); c.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.0.3705; .NET CLR 1.1.4322; .NET CLR 1.2.30703)"); InputStream input; input = c.getInputStream(); byte[] buffer = new byte[4096]; int n = -1; OutputStream output = new FileOutputStream(new File(fileName)); while ((n = input.read(buffer)) != -1) { if (n > 0) { output.write(buffer, 0, n); } } output.close();

Pero puedo descargar con éxito el siguiente archivo de mi Dropbox ( http://dl.dropbox.com/u/13226123/ChampionHelper-4.jar ) con el mismo método.

Entonces, de alguna manera, Github sabe que no soy un usuario habitual que intenta descargar un archivo. Ya intenté cambiar el agente de usuario, pero tampoco ayudó.

Entonces, ¿cómo debo descargar un archivo alojado en mi cuenta Github utilizando Java?

EDITAR: Intenté usar apache commons-io para esto, pero obtengo el mismo efecto, un archivo vacío / corrupto.


Encontré la solución.

Aparentemente, http://github.com/downloads/TheHolyWaffle/ChampionHelper/ChampionHelper-4.jar no vincula directamente a mi archivo.

Al ver el jar resultante con un editor de texto encontré esto:

<html><body>You are being <a href="http://cloud.github.com/downloads/TheHolyWaffle/ChampionHelper/ChampionHelper-4.jar">redirected</a>.</body></html>

Esto significa que el enlace directo es el siguiente: http://cloud.github.com/downloads/TheHolyWaffle/ChampionHelper/ChampionHelper-4.jar

Y con este enlace puedo descargar el archivo con mi método sin ningún problema.


Este hace el trabajo:

public class Download { private static boolean isRedirected( Map<String, List<String>> header ) { for( String hv : header.get( null )) { if( hv.contains( " 301 " ) || hv.contains( " 302 " )) return true; } return false; } public static void main( String[] args ) throws Throwable { String link = "http://github.com/downloads/TheHolyWaffle/ChampionHelper/" + "ChampionHelper-4.jar"; String fileName = "ChampionHelper-4.jar"; URL url = new URL( link ); HttpURLConnection http = (HttpURLConnection)url.openConnection(); Map< String, List< String >> header = http.getHeaderFields(); while( isRedirected( header )) { link = header.get( "Location" ).get( 0 ); url = new URL( link ); http = (HttpURLConnection)url.openConnection(); header = http.getHeaderFields(); } InputStream input = http.getInputStream(); byte[] buffer = new byte[4096]; int n = -1; OutputStream output = new FileOutputStream( new File( fileName )); while ((n = input.read(buffer)) != -1) { output.write( buffer, 0, n ); } output.close(); } }


Obtenga el enlace de descarga directa al archivo binario sin formato, por ejemplo, https://github.com/xerial/sqlite-jdbc/blob/master/src/main/resources/org/sqlite/native/Windows/x86_64/sqlitejdbc.dll?raw = verdadero al copiar el enlace View Raw :

Finalmente use la siguiente pieza de código para descargar el archivo:

public static void download(String downloadURL) throws IOException { URL website = new URL(downloadURL); String fileName = getFileName(downloadURL); try (InputStream inputStream = website.openStream()) { Files.copy(inputStream, Paths.get(fileName), StandardCopyOption.REPLACE_EXISTING); } } public static String getFileName(String downloadURL) { String baseName = FilenameUtils.getBaseName(downloadURL); String extension = FilenameUtils.getExtension(downloadURL); String fileName = baseName + "." + extension; int questionMarkIndex = fileName.indexOf("?"); if (questionMarkIndex != -1) { fileName = fileName.substring(0, questionMarkIndex); } fileName = fileName.replaceAll("-", ""); return URLDecoder.decode(fileName, "UTF-8"); }

También necesitarás la dependencia Maven de Apache Commons IO para la clase FilenameUtils :

<dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>LATEST</version> </dependency>


Parece que GitHub le proporciona varios niveles de redireccionamientos cuando solicita este archivo y este artículo de establece que URLConnection no seguirá automáticamente los redireccionamientos que cambian el protocolo. Esto es lo que estoy viendo con curl:

Primera solicitud:

curl -v http://github.com/downloads/TheHolyWaffle/ChampionHelper/ChampionHelper-4.jar * About to connect() to github.com port 80 (#0) * Trying 207.97.227.239... connected * Connected to github.com (207.97.227.239) port 80 (#0) > GET /downloads/TheHolyWaffle/ChampionHelper/ChampionHelper-4.jar HTTP/1.1 > User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5 > Host: github.com > Accept: */* > < HTTP/1.1 301 Moved Permanently < Server: nginx < Date: Sun, 18 Nov 2012 15:56:36 GMT < Content-Type: text/html < Content-Length: 178 < Connection: close < Location: https://github.com/downloads/TheHolyWaffle/ChampionHelper/ChampionHelper-4.jar < <html> <head><title>301 Moved Permanently</title></head> <body bgcolor="white"> <center><h1>301 Moved Permanently</h1></center> <hr><center>nginx</center> </body> </html> * Closing connection #0

Un rizo de este encabezado de ubicación:

curl -v https://github.com/downloads/TheHolyWaffle/ChampionHelper/ChampionHelper-4.jar * About to connect() to github.com port 443 (#0) * Trying 207.97.227.239... connected * Connected to github.com (207.97.227.239) port 443 (#0) * SSLv3, TLS handshake, Client hello (1): * SSLv3, TLS handshake, Server hello (2): * SSLv3, TLS handshake, CERT (11): * SSLv3, TLS handshake, Server finished (14): * SSLv3, TLS handshake, Client key exchange (16): * SSLv3, TLS change cipher, Client hello (1): * SSLv3, TLS handshake, Finished (20): * SSLv3, TLS change cipher, Client hello (1): * SSLv3, TLS handshake, Finished (20): * SSL connection using RC4-SHA * Server certificate: * subject: businessCategory=Private Organization; 1.3.6.1.4.1.311.60.2.1.3=US; 1.3.6.1.4.1.311.60.2.1.2=California; serialNumber=C3268102; C=US; ST=California; L=San Francisco; O=GitHub, Inc.; CN=github.com * start date: 2011-05-27 00:00:00 GMT * expire date: 2013-07-29 12:00:00 GMT * subjectAltName: github.com matched * issuer: C=US; O=DigiCert Inc; OU=www.digicert.com; CN=DigiCert High Assurance EV CA-1 * SSL certificate verify ok. > GET /downloads/TheHolyWaffle/ChampionHelper/ChampionHelper-4.jar HTTP/1.1 > User-Agent: curl/7.21.4 (universal-apple-darwin11.0) libcurl/7.21.4 OpenSSL/0.9.8r zlib/1.2.5 > Host: github.com > Accept: */* > < HTTP/1.1 302 Found < Server: nginx < Date: Sun, 18 Nov 2012 15:58:56 GMT < Content-Type: text/html; charset=utf-8 < Connection: keep-alive < Status: 302 Found < Strict-Transport-Security: max-age=2592000 < Cache-Control: no-cache < X-Runtime: 48 < Location: http://cloud.github.com/downloads/TheHolyWaffle/ChampionHelper/ChampionHelper-4.jar < X-Frame-Options: deny < Content-Length: 149 < * Connection #0 to host github.com left intact * Closing connection #0 * SSLv3, TLS alert, Client hello (1): <html><body>You are being <a href="http://cloud.github.com/downloads/TheHolyWaffle/ChampionHelper/ChampionHelper-4.jar">redirected</a>.</body></html>

El encabezado de ubicación en esta respuesta devuelve el archivo real. Es posible que desee utilizar Apache HTTP Client para descargar esto. Puede configurarlo para seguir estos 301 y 302 redireccionamientos durante el GET.