• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

java实现高效下载文件的方法

java 搞代码 4年前 (2022-01-09) 30次浏览 已收录 0个评论

本文实例为大家分享了java实现下载文件的方法,供大家参考,具体内容如下

本文我们介绍几种方法下载文件。从基本JAVA IO 到 NIO包,也介绍第三方库的一些方法,如Async Http Client 和 Apache Commons IO.
最后我们还讨论在连接断开后如何恢复下载。

使用java IO

下载文件最基本的方法是java I本文来源gaodaima#com搞(代@码$网6O,使用URL类打开待下载文件的连接。为有效读取文件,我们使用openStream() 方法获取 InputStream:

BufferedInputStream in = new BufferedInputStream(new URL(FILE_URL).openStream())

当从InputStream读取文件时,强烈建议使用BufferedInputStream去包装InputStream,用于提升性能。
使用缓存可以提升性能。read方法每次读一个字节,每次方法调用意味着系统调用底层的文件系统。当JVM调用read()方法时,程序执行上下文将从用户模式切换到内核模式并返回。

从性能的角度来看,这种上下文切换非常昂贵。当我们读取大量字节时,由于涉及大量上下文切换,应用程序性能将会很差。

为了读取URL的字节并写至本地文件,需要使用FileOutputStream 类的write方法:

try (BufferedInputStream in = new BufferedInputStream(new URL(FILE_URL).openStream());
  FileOutputStream fileOutputStream = new FileOutputStream(FILE_NAME)) {
    byte dataBuffer[] = new byte[1024];
    int bytesRead;
    while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) {
        fileOutputStream.write(dataBuffer, 0, bytesRead);
    }
} catch (IOException e) {
    // handle exception
}

使用BufferedInputStream,read方法按照我们设置缓冲器大小读取文件。示例中我们设置一次读取1024字节,所以BufferedInputStream 是必要的。

上述示例代码冗长,幸运的是在Java7中Files类包含处理IO操作的助手方法。可以使用File.copy()方法从InputStream中读取所有字节,然后复制至本地文件:

InputStream in = new URL(FILE_URL).openStream();
Files.copy(in, Paths.get(FILE_NAME), StandardCopyOption.REPLACE_EXISTING);

上述代码可以正常工作,但缺点是字节被缓冲到内存中。Java为我们提供了NIO包,它有方法在两个通道之间直接传输字节,而无需缓冲。下面我们会详细讲解。

使用NIO

java NIO包提供了无缓冲情况下在两个通道之间直接传输字节的可能。

为了读来自URL的文件,需从URL流创建ReadableByteChannel :

ReadableByteChannel readableByteChannel = Channels.newChannel(url.openStream());

从ReadableByteChannel 读取字节将被传输至FileChannel:

FileOutputStream fileOutputStream = new FileOutputStream(FILE_NAME);
FileChannel fileChannel = fileOutputStream.getChannel();

然后使用transferFrom方法,从ReadableByteChannel 类下载来自URL的字节传输到FileChannel:

fileOutputStream.getChannel()
  .transferFrom(readableByteChannel, 0, Long.MAX_VALUE);

transferTo() 和 transferFrom() 方法比简单使用缓存从流中读更有效。依据不同的底层操作系统,数据可以直接从文件系统缓存传输到我们的文件,而不必将任何字节复制到应用程序内存中。

在Linux和UNIX系统上,这些方法使用零拷贝技术,减少了内核模式和用户模式之间的上下文切换次数。

使用第三方库

上面我们已经使用java 核心功能实现从URL下载文件。当无需调整性能是,我们也可以利用第三方库轻松实现。举例,在实际场景中,需要实现异步下载,我们可以封装逻辑至Callable,下面看已有库实现。


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:java实现高效下载文件的方法

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址