java中文件复制的4种方式
今天一个同事问我文件复制的问题,他一个100M的文件复制的指定目录下竟然成了1G多,吓我一跳,后来看了他的代码发现是自己通过字节流复制的,定义的字节数组很大,导致复制后目标文件非常大,其实就是空行等一些无效空间。我也是很少用这种方式拷贝问价,大多数用Apache提供的commons-io中的FileUtils,后来在网上查了下,发现还有其他的方式,效率更高,所以在此整理一下,也是自己的一个学习。
1. 使用FileStreams复制
比较经典的一个代码,使用FileInputStream读取文件A的字节,使用FileOutputStream写入到文件B。
public static void copy(String source, String dest, int bufferSize) {
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(new File(source));
out = new FileOutputStream(new File(dest));
byte[] buffer = new byte[bufferSize];
int len;
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
} catch (Exception e) {
Log.w(TAG + ":copy", "error occur while copy", e);
} finally {
safelyClose(TAG + ":copy", in);
safelyClose(TAG + ":copy", out);
}
}
2.
2、使用FileChannel
Java NIO包括transferFrom方法,根据文档应该比文件流复制的速度更快。
public static void copyNio(String source, String dest) {
FileChannel input = null;
FileChannel output = null;
try {
input = new FileInputStream(new File(from)).getChannel();
output = new FileOutputStream(new File(to)).getChannel();
output.transferFrom(input, 0, input.size());
} catch (Exception e) {
Log.w(TAG + "copyNio", "error occur while copy", e);
} finally {
safelyClose(TAG + "copyNio", input);
safelyClose(TAG + "copyNio", output);
}
}
3、 使用Apache Commons IO复制
Appache Commons IO 提供了一个FileUtils.copyFile(File from, File to)
方法用于文件复制,如果项目里使用到了这个类库,使用这个方法是个不错的选择。
它的内部也是使用Java NIO的FileChannel
实现的。
commons-io的路径:http://commons.apache.org/proper/commons-io/javadocs/api-release/index.html。里面还有很多实用的方法,如拷贝目录、拷贝指定格式文件等。
private static void copyFileByApacheCommonsIO(File source, File dest) throws IOException {
FileUtils.copyFile(source, dest);
}
4、使用Java7的Files类复制
private static void copyFileUsingJava7Files(File source, File dest) throws IOException {
Files.copy(source.toPath(), dest.toPath());
}
我没有亲测,找了下网友的测试程序和输出,性能数据供大家参考(来源:https://www.jb51.net/article/70412.htm)
import
java.io.File;
import
java.io.FileInputStream;
import
java.io.FileOutputStream;
import
java.io.IOException;
import
java.io.InputStream;
import
java.io.OutputStream;
import
java.nio.channels.FileChannel;
import
java.nio.file.Files;
import
org.apache.commons.io.FileUtils;
public
class
CopyFilesExample {
public
static
void
main(String[] args)
throws
InterruptedException,
IOException {
File source =
new
File(
"C:\\Users\\nikos7\\Desktop\\files\\sourcefile1.txt"
);
File dest =
new
File(
"C:\\Users\\nikos7\\Desktop\\files\\destfile1.txt"
);
// copy file using FileStreams
long
start = System.nanoTime();
long
end;
copyFileUsingFileStreams(source, dest);
System.out.println(
"Time taken by FileStreams Copy = "
+ (System.nanoTime() - start));
// copy files using java.nio.FileChannel
source =
new
File(
"C:\\Users\\nikos7\\Desktop\\files\\sourcefile2.txt"
);
dest =
new
File(
"C:\\Users\\nikos7\\Desktop\\files\\destfile2.txt"
);
start = System.nanoTime();
copyFileUsingFileChannels(source, dest);
end = System.nanoTime();
System.out.println(
"Time taken by FileChannels Copy = "
+ (end - start));
// copy file using Java 7 Files class
source =
new
File(
"C:\\Users\\nikos7\\Desktop\\files\\sourcefile3.txt"
);
dest =
new
File(
"C:\\Users\\nikos7\\Desktop\\files\\destfile3.txt"
);
start = System.nanoTime();
copyFileUsingJava7Files(source, dest);
end = System.nanoTime();
System.out.println(
"Time taken by Java7 Files Copy = "
+ (end - start));
// copy files using apache commons io
source =
new
File(
"C:\\Users\\nikos7\\Desktop\\files\\sourcefile4.txt"
);
dest =
new
File(
"C:\\Users\\nikos7\\Desktop\\files\\destfile4.txt"
);
start = System.nanoTime();
copyFileUsingApacheCommonsIO(source, dest);
end = System.nanoTime();
System.out.println(
"Time taken by Apache Commons IO Copy = "
+ (end - start));
}
private
static
void
copyFileUsingFileStreams(File source, File dest)
throws
IOException {
InputStream input =
null
;
OutputStream output =
null
;
try
{
input =
new
FileInputStream(source);
output =
new
FileOutputStream(dest);
byte
[] buf =
new
byte
[
1024
];
int
bytesRead;
while
((bytesRead = input.read(buf)) >
0
) {
output.write(buf,
0
, bytesRead);
}
}
finally
{
input.close();
output.close();
}
}
private
static
void
copyFileUsingFileChannels(File source, File dest)
throws
IOException {
FileChannel inputChannel =
null
;
FileChannel outputChannel =
null
;
try
{
inputChannel =
new
FileInputStream(source).getChannel();
outputChannel =
new
FileOutputStream(dest).getChannel();
outputChannel.transferFrom(inputChannel,
0
, inputChannel.size());
}
finally
{
inputChannel.close();
outputChannel.close();
}
}
private
static
void
copyFileUsingJava7Files(File source, File dest)
throws
IOException {
Files.copy(source.toPath(), dest.toPath());
}
private
static
void
copyFileUsingApacheCommonsIO(File source, File dest)
throws
IOException {
FileUtils.copyFile(source, dest);
}
}
输出:
Time taken by FileStreams Copy =
127572360
Time taken by FileChannels Copy =
10449963
Time taken by Java7 Files Copy =
10808333
Time taken by Apache Commons IO Copy =
17971677
java中文件复制的4种方式的更多相关文章
- java中数组复制的两种方式
在java中数组复制有两种方式: 一:System.arraycopy(原数组,开始copy的下标,存放copy内容的数组,开始存放的下标,需要copy的长度); 这个方法需要先创建一个空的存放cop ...
- Java实现文件复制的四种方式
背景:有很多的Java初学者对于文件复制的操作总是搞不懂,下面我将用4中方式实现指定文件的复制. 实现方式一:使用FileInputStream/FileOutputStream字节流进行文件的复制操 ...
- Java中数组复制的几种方式以及数组合并
1.Object.clone() 简单直接,只能对源数组完整地复制 2.Arrays.copyOf(T[] original, int newLength) 可以只复制源数组中部分元素,但复制的起始位 ...
- Java中HashMap遍历的两种方式
Java中HashMap遍历的两种方式 转]Java中HashMap遍历的两种方式原文地址: http://www.javaweb.cc/language/java/032291.shtml 第一种: ...
- JAVA中集合输出的四种方式
在JAVA中Collection输出有四种方式,分别如下: 一) Iterator输出. 该方式适用于Collection的所有子类. public class Hello { public stat ...
- java中使用mongodb的几种方式
最近有时间看了一下mongodb,因为mongodb更容易扩展所以考虑使用mongodb来保存数据. 首先下载安装mongodb,这是很简单的,装好后使用mongod命令就可以启动数据库.正式部署的话 ...
- java中设置代理的两种方式
1 前言 有时候我们的程序中要提供可以使用代理访问网络,代理的方式包括http.https.ftp.socks代理.比如在IE浏览器设置代理. 那我们在我们的java程序中使用代理呢,有如下两种方式. ...
- java中实现同步的两种方式:syschronized和lock的区别和联系
Lock是java.util.concurrent.locks包下的接口,Lock 实现提供了比使用synchronized 方法和语句可获得的更广泛的锁定操作,它能以更优雅的方式处理线程同步问题,我 ...
- java中遍历集合的三种方式
第一种遍历集合的方式:将集合变为数组 package com.lw.List; import java.util.ArrayList; import java.util.List; import ja ...
随机推荐
- 谈架构设计中DDD思想的运用
首先,描述一下我的业务场景及项目分层结构,非标准DDD(其实我不觉得有标准),只是思考的时候有带入DDD思想. 业务场景:这是一个ERP系统对中台提供的接口项目,仓储操作大多都是存储过程去完成的. 项 ...
- python笔记01
一.编码: (一)编码分类 ①ascii编码: 占有1个字节,8位,可表示2**8个字符,(py2默认编码方式). ②unicode: 万国码,占有4个字节,32位,可表示2**32个字符. ③utf ...
- [TimLinux] JavaScript table的td内容超过宽度缩为三个点
1. 思路 CSS控制td内容自动缩为三个点 JS控制鼠标悬浮显示td全部内容 2. 实现 HTML代码: <!DOCTYPE html> <html> <head> ...
- 初探hook的键盘获取
初探hook的键盘获取 import pyHook import pythoncom class e(): keyIsPressed = False #键盘是否按下 按住.. def onKeyDow ...
- 基于CC1606 FPGA评估板移植iCamera程序小结
iCamera作为柴草电子经典的摄像头开发工具,其强大的摄像头调试功能,深受广大网友喜爱,支持市面上各种摄像头. 目前现有的应用板卡支持:CC1601(CP601A). CC1602(CP601B) ...
- 使用iCamera 测试MT9F002 1400w高分辨率摄像头小结 之!!看清细节!!!
使用iCamera 测试MT9F002 1400w高分辨率摄像头小结 之!!看清细节!!! 本方案测试两种种分辨率输出(其他更多分辨率设置,可以参考手册配置) 4608*3288=1515万像素 11 ...
- JavaWeb中的MVC 下
代码较多,请先略过代码,看懂逻辑在研究代码 引入 回顾上一节中的项目,最终的层次结构: 在MVC上中,我们分析了MVC设计模式具备的优点,以及不足,并在其基础上增了Service层用于处理业务逻辑,但 ...
- hdu 1010 Tempter of the Bone(深搜+奇偶剪枝)
Tempter of the Bone Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Othe ...
- AWS re:Invent 2019参会有感
感谢AWS方面的邀请,以及公司给予的机会,近期有幸赴美参与了享有盛名的AWS re:Invent大会.会议期间自己还算勤勉,参加了尽可能多的session.现笔者也已回到国内,交个作业,写一篇短文作为 ...
- 原创 Hive left join 技巧总结
根据工作中经验总结出来 left join 常用的 使用注意点: A Left join B on A.id = B.id 第一种情况: 如果 A 表 ...