Java文件拷贝方式
原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11444284.html
利用java.io类库,直接为源文件构建一个FileInputStream读取,然后再为目标文件构建一个FileOutputStream,完成写入工作。
public static void copyFileByStream(File source, File dest) throws IOException {
try (InputStream is = new FileInputStream(source);
OutputStream os = new FileOutputStream(dest)) {
byte[] buffer = new byte[1024];
int length;
while ((length = is.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
}
}
利用java.nio类库提供的transferTo或transferFrom方法实现
public static void copyFileByChannel(File source, File dest) throws IOException {
try (FileChannel sourceChannel = new FileInputStream(source).getChannel();
FileChannel targetChannel = new FileOutputStream(dest).getChannel()) {
for (long count = sourceChannel.size(); count > 0; ) {
long transferred = sourceChannel.transferTo(sourceChannel.position(), count, targetChannel);
sourceChannel.position(sourceChannel.position() + transferred);
count -= transferred;
}
}
}
Java标准类库提供的几种Files.copy的实现

对于Copy的效率,这个其实与操作系统和配置等情况相关,总体上来说,NIO transferTo/From的方式可能更快,因为它更能利用现代操作系统底层机制,避免不必要拷贝和上下文切换。
拷贝实现机制分析
先来理解一下,前面实现的不同拷贝方法,本质上有什么明显的区别。
首先,需要理解用户态空间(User Space)和内核态空间(Kernel Space),这是操作系统层面的基本概念,操作系统内核、硬件驱动等运行在内核态空间,具有相对高的特权;而用户态空间,则是给普通应用和服务使用。可以参考:https://en.wikipedia.org/wiki/User_space。
当使用输入输出流进行读写时,实际上是进行了多次上下文切换,比如应用读取数据时,先在内核态将数据从磁盘读取到内核缓存,再切换到用户态将数据从内核缓存读取到用户缓存。
写入操作也是类似,仅仅是步骤相反,可以参考下面这张图。

所以,这种方式会带来一定的额外开销,可能会降低IO效率。
而基于NIO transferTo的实现方式,在Linux和Unix上,则会使用到零拷贝技术,数据传输并不需要用户态参与,省去了上下文切换的开销和不必要的内存拷贝,进而可能提高应用拷贝性能。注意,transferTo不仅仅是可以用在文件拷贝中,与其类似的,例如读取磁盘文件,然后进行Socket发送,同样可以享受这种机制带来的性能和扩展性提高。
transferTo的传输过程是:

Reference
https://time.geekbang.org/column/article/8393
Java文件拷贝方式的更多相关文章
- 【Java面试】Java有几种文件拷贝方式,哪一种效率最高?
"Java有几种文件拷贝方式,哪一种效率最高?" 这个问题是京东一面的时候,针对4年经验的同学的一个面试题. 大家好,我是Mic,一个工作了14年的Java程序员. 关于这个问题的 ...
- java 文件拷贝
需求:源和目标! 那么我们需要源文件和目标文件! 构建管道的时候就需要两个:输出流和输入流管道! Eg: package july7file; //java7开始的自动关闭资源 import java ...
- Java文件拷贝
package com.lxm.demos; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io. ...
- Java 对象拷贝方式
(1)BeanUtils.cloneBean()使用: http://www.cnblogs.com/fervour/archive/2009/12/18/1627868.html package c ...
- IO复制多级目录 控制台输入文件目录然后把目录下java文件复制到 D: 并统计java个数
package cn.itcast_05; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; impor ...
- linux几种传输方式与拷贝方式的性能分析
本文记录linux系统中文件传输的多种方式,留作备忘.linux中文件传输的方式有ftp,scp,rsync,rz,sz等,但各个工具的功能又有所区别: FTP : FTP是文件服务器,可实现文件的上 ...
- java 四种方式实现字符流文件的拷贝对比
将D:\\应用软件\\vm.exe 拷贝到C:\\vm.exe 四种方法耗费时间对比 4>2>3>1 package Copy; import java.io.Buffere ...
- 总结java中文件拷贝剪切的5种方式-JAVA IO基础总结第五篇
本文是Java IO总结系列篇的第5篇,前篇的访问地址如下: 总结java中创建并写文件的5种方式-JAVA IO基础总结第一篇 总结java从文件中读取数据的6种方法-JAVA IO基础总结第二篇 ...
- Java IO和Java NIO在文件拷贝上的性能差异分析
1. 在JAVA传统的IO系统中,读取磁盘文件数据的过程如下: 以FileInputStream类为例,该类有一个read(byte b[])方法,byte b[]是我们要存储读取到用户空间的缓冲区 ...
随机推荐
- 数据库索引(BTree索引和Hash索引)
索引 索引是为了方便查找我们所需要的数据. mysql支持的索引数据类型 B-Tree索引的特点 B-Tree索引以B+Tree(树)的结构存储数据. B-Tree索引能够加快数据的查询速度: B-T ...
- docker 运行springboot jar包
1.将jar包移至自定义的/usr/jar目录下; 2.在/usr/jar目录下创建Dockerfile文件 文件如下: #FROM命令定义构建镜像的基础镜像,该条必须是dockerfile的首个命令 ...
- SQL IN 运算符
SQL IN 运算符 IN运算符允许您在WHERE子句中指定多个值. IN运算符是多个OR条件的简写. SQL IN 语法 SELECT column_name(s) FROM table_name ...
- shell脚本编程测试类型下
一bash的数值测试 -v VAR变量VAR是否设置 数值测试:-gt 是否大于greater-ge 是否大于等于-eq 是否等于-ne 是否不等于 not equal-lt 是否小于-le 是否小 ...
- .net从服务端下载文件(可以断点续传)
public void DownFile(string guid) { var fileTransfer = new FileTransfer(); var directoryPath = Path. ...
- JRE和JVM的区别
JRE和JVM的区别 JRE(JavaRuntimeEnvironment,Java运行环境),也就是Java平台.所有的Java程序都要在JRE下才能运行.JDK的工具也是Java程序, ...
- SQL中循环的实现方式
一.第一种方法,游标 定义游标 DECLARE cur_ClubHeadCash CURSOR FAST_FORWARD READ_ONLY FOR,循环每行 FETCH NEXT FROM cur_ ...
- CentOS 6.9 安装配置zeromq、jzmq
官方安装配置链接 安装zeromq 步骤一.准备C语言环境 yum -y install gcc-c++ 步骤二.解压缩zeromq tar -zxf zeromq-4.1.6.tar.gz 步骤三. ...
- iOS 完全复制UIView
如果要完全复制一个UIView和对象的时候可以使用对象序列化方法 // Duplicate UIView - (UIView*)duplicate:(UIView*)view { NSData * t ...
- iOS 获取self类型
类型转换快速写法 typeof(self) bself = self; 版权声明:本文为博主原创文章,未经博主允许不得转载.