17

I want to make a Java application that when executed downloads a file from a URL. Is there any function that I can use in order to do this?

This piece of code worked only for a .txt file:

URL url= new URL("http://cgi.di.uoa.gr/~std10108/a.txt");
BufferedReader in = new BufferedReader(
new InputStreamReader(url.openStream()));
PrintWriter writer = new PrintWriter("file.txt", "UTF-8");

String inputLine;
while ((inputLine = in.readLine()) != null){
   writer.write(inputLine+ System.getProperty( "line.separator" ));               
   System.out.println(inputLine);
}
writer.close();
in.close();
Sled
  • 16,514
  • 22
  • 110
  • 148
JmRag
  • 1,310
  • 6
  • 15
  • 47

1 Answers1

33

Don't use Readers and Writers here as they are designed to handle raw-text files which PDF is not (since it also contains many other information like info about font, and even images). Instead use Streams to copy all raw bytes.

So open connection using URL class. Then just read from its InputStream and write raw bytes to your file.

(this is simplified example, you still need to handle exceptions and ensure closing streams in right places)

System.out.println("opening connection");
URL url = new URL("https://upload.wikimedia.org/wikipedia/en/8/87/Example.JPG");
InputStream in = url.openStream();
FileOutputStream fos = new FileOutputStream(new File("yourFile.jpg"));

System.out.println("reading from resource and writing to file...");
int length = -1;
byte[] buffer = new byte[1024];// buffer for portion of data from connection
while ((length = in.read(buffer)) > -1) {
    fos.write(buffer, 0, length);
}
fos.close();
in.close();
System.out.println("File downloaded");

Since Java 7 we can also use Files.copy and the try-with-resources to automatically close the InputStream (the stream doesn't have to be closed manually in this case):

URL url = new URL("https://upload.wikimedia.org/wikipedia/en/8/87/Example.JPG");
try (InputStream in = url.openStream()) {
   Files.copy(in, Paths.get("someFile.jpg"), StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
   // handle exception
}
Pshemo
  • 113,402
  • 22
  • 170
  • 242
  • Did you mean to use the assignment operator as the parameter of the while loop? – louie mcconnell Dec 18 '15 at 06:04
  • @louiemcconnell Yes. This logic is same as in first example from: http://docs.oracle.com/javase/tutorial/networking/urls/readingWriting.html but instead of reading lines I am reading bytes. – Pshemo Dec 18 '15 at 15:15