Given the following example code:
somefile = new URL("http://somefile.rar");
ReadableByteChannel rbc = Channels.newChannel(somefile.openStream());
FileOutputStream fos = new FileOutputStream("test");
long start = System.currentTimeMillis();
fos.getChannel().transferFrom(rbc, 0, 1 << 24);
long end = System.currentTimeMillis();
System.out.println(end-start);
The file in question is 14MB. When I download it using the code above, it takes 26-30 seconds every time. I noticed that, when downloading it from java, there are periods where no bytes are being transferred at all. When I download the same file from, say, a browser, it downloads in 4 seconds or less. Any idea what the problem is here?
Using channels is a nice idea, since you can this way avoid superfluous copying of data in memory. But you are using not a real socket-channel here, but a wrapper channel around the InputStream from your URL, which ruins your experience.
You may be able to implement the HTTP protocol yourself using a SocketChannel, or find some library which allows this. (But then, if the result is sent using chunked-encoding, you’ll still have to parse this yourself.)
So, the easier way would be to use simply the usual stream copying way given by the other answers.