开发者

downloading to a file in Java - very slow

Given the following example code:

somefile = new URL("http://somefile.rar");
ReadableByteChannel rbc = Channels.newChannel(somefile.openStream());
FileOutputStream fos = new FileOutput开发者_开发知识库Stream("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?


I've never seen this way of downloading. Maybe you should try with a BufferedInputStream:

URL url = new URL("http://yourfile.rar");
File target = new File("package.rar");

try (BufferedInputStream bis = new BufferedInputStream(url.openStream())) {
    try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(target))) {
        byte[] buffer = new byte[4096];
        int bytesRead;
        while ((bytesRead = bis.read(buffer)) != -1) {
            bos.write(buffer, 0, bytesRead);
        }
        bos.flush();
    }
}


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.


A suggestion - why don't try removing the channels and work only with the streams. For example you can use commons-io

IOUtils.copy(new BufferedInputStream(somefile.openStream()), 
       new BufferedOutputStream(fos));
// of course, you'd have to close the streams at the end.


A better way to use common-io to download file :

FileUtils.copyUrlToFile(URL url, String destination);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜