简体   繁体   中英

Downloading binary file from url

I am using this code to download files from a url:

FileUtils.copyURLToFile(url, new File("C:/Songs/newsong.mp3"));

When I create the url using for instance, " https://mjcdn.cc/2/282676442/MjUgU2FhbCAtIFZlZXQgQmFsaml0Lm1wMw== ", this works just fine and the mp3 is downloaded. However, if I use another url: " https://dl.jatt.link/hd.jatt.link/a0339e7c772ed44a770a3fe29e3921a8/uttzv/Hummer-(Mr-Jatt.com).mp3 ", the file is 0kb.

I am able to download files from both these urls from within a web browser. What's wrong here, and how can I fix it.

I noticed a difference between your 2 URLs:

  • The first one just gives back the file without redirection .
  • But the second one responds with a redirect ( HTTP/1.1 302 Moved Temporarily ). It's also a special case, because it's a redirect from HTTPS to HTTP protocol.

Browsers can follow redirects, but your program - for some reason (see below) - can't.

I suggest you to use a HTTP client library (eg Apache HTTP client or Jsoup ), and configure it to follow redirects (if they don't do it by default).

For example, with Jsoup, you would need a code like this:

String url = "https://dl.jatt.link/hd.jatt.link/a0339e7c772ed44a770a3fe29e3921a8/uttzv/Hummer-(Mr-Jatt.com).mp3";
String filename = "C:/Songs/newsong.mp3";
Response r = Jsoup.connect(url)
    //.followRedirects(true) // follow redirects (it's the default)
    .ignoreContentType(true) // accept not just HTML
    .maxBodySize(10*1000*1000) // accept 10M bytes (default is 1M), or set to 0 for unlimited
    .execute(); // send GET request
FileOutputStream out = new FileOutputStream(new File(filename));
out.write(r.bodyAsBytes());
out.close();

Update on @EJP's comment:

  • I looked up Apache Commons IO's FileUtils class on GitHub . It calls openStream() of the received URL object.
  • openStream() is a shorthand for openConnection().inputStream() .
  • openConnection() returns an URLConnection object. If there is an appropriate subclass for the protocol used by URL , it will return an instance of that subclass. In this case that's a HttpsURLConnection which is the subclass of HttpURLConnection .
  • The followRedirects option is defined in HttpURLConnection and it's indeed true by default:

Sets whether HTTP redirects (requests with response code 3xx) should be automatically followed by this class. True by default.

  • So OP's approach would normally work with redirects too, but it seems that redirection from HTTPS to HTTP is not handled (properly) by HttpsURLConnection . - It's the case that @VGR mentioned in the comments below.
  • It's possible to handle redirects manually by reading the Location header with HttpsURLConnection , then use it in a new HttpURLConnection . ( Example ) (I wouldn't be surprised if Jsoup did the same.)
  • I suggested Jsoup because it already implements a way to handle HTTPS to HTTP redirections correctly and also provides tons of useful features.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM