Java文件拷贝方式?哪一种最高效?

问题:

Java有几种文件拷贝方式?哪一种最高效?

知识点补充:

  1. 拷贝实现机制分析
  2. image

从上图可知,当我们使用输入输出流进行读写时,实际上是进行了多次上下文切换,比如应用读取数据时,先在内核态讲数据从磁盘读取到内核缓存,再切换到用户态将数据从内核缓存读取到用户缓存。写入操作类似。

image

而基于NIO transferTo的实现方式,在Linux和Unix上,会使用零拷贝技术,数据传输并不需要用户态参与,省去了上下午切换的开销和不必要的内存拷贝,进而可提高应用拷贝性能。

注意:transferTo不仅仅是可以用在文件拷贝中,与其类似的,例如读取磁盘文件,然后进行Socket发送,同样可以享受这种机制带来的性能和扩展性提高。突然想到日志开发中使用到的mmap和其类似,又不一样,有兴趣可以参考:认真分析mmap:是什么 为什么 怎么用

回答问题:

Java有多种比较典型的文件拷贝实现方式,比如:
利用java.io类库,直接为源文件构建一个FileInputStream读取,然后再为目标文件构建一个FileOutputStream,完成写入工作。

1
2
3
4
5
6
7
8
9
10
public static void copyFileByStream(File source,File dest) throws IOException{
try(InputStream inputStream = new FileInputStream(source);
OutputStream outputStream = new FileOutputStream(dest)){
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer))>0){
outputStream.write(buffer,0,length);
}
}
}

或者,利用java.nio类库提供的transferTo或者transferFrom方法实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/**
* 复制文件,使用nio以提高性能
*
* @param src - 源文件
* @param dest - 目标文件
*/
public static void copyFile(File src, File dest) {
FileInputStream fis = null;
FileOutputStream fos = null;
FileChannel in = null;
FileChannel out = null;
try {
fis = new FileInputStream(src);
fos = new FileOutputStream(dest);
in = fis.getChannel(); // 得到对应的文件通道
out = fos.getChannel(); // 得到对应的文件通道
in.transferTo(0, in.size(), out); // 连接两个通道,并且从in通道读取,然后写入out通道
} catch (IOException e) {
e.printStackTrace();
} finally {
IoUtils.closeQuietly(fis);
IoUtils.closeQuietly(in);
IoUtils.closeQuietly(fos);
IoUtils.closeQuietly(out);
}
}

当然,Java标准类库本身已经提供了几种File.copy方法的实现(我在Android目前还没用到),或者使用使用Apache Commons IO提供的提供了一个FileUtils.copyFile(File from, File to)方法用于文件复制,如果项目里使用到了这个类库,使用这个方法是个不错的选择。它的内部也是使用Java NIO的FileChannel实现的(我在Android目前还没用到)。有兴趣可以参考:文件复制的 4 种实现方式及性能对比

对于Copy的效率,这个其实与操作系统和配置等情况有关。总体来说,NIO transferTo/From的方式可能更快,因为它更能利用现在操作系统底层机制,避免不必要的拷贝和上下文切换

参考:

声明:此为原创,转载请联系作者


作者:微信公众号添加公众号-遛狗的程序员 ,或者可以扫描以下二维码关注相关技术文章。

qrcode_for_gh_1ba0785324d6_430.jpg

当然喜爱技术,乐于分享的你也可以可以添加作者微信号:

WXCD.jpeg

文章目录
  1. 1. 问题:
  2. 2. 知识点补充:
  3. 3. 回答问题:
|