在Java编程中,复制文件的方法有很多,而且经常要用到。绝大多数人都是缓冲输入输出流来实现的,我也是如此,其实在新的JDK中出现了一种用文件通道(FileChannel)来实现文件复制的方法,而且这种竟然比用文件流快了近三分之一,同时无须处理异常。一般在JDK1.6以上含本数,则可以使用高效,代码简短的方法。
旧式复制单个文件的方法如下:
/**
* 使用文件流的方式复制文件
*
* @param soutrce
* 源文件
* @param target
* 复制到的新文件
*/
public static boolean fileStreamCopy(File source, File target) throws Exception {
if(!source.exists()){
System.out.println("源文件不存在!");
return false;
}
File targetPath = new File(target.getParent());
if(!targetPath.exists()){
targetPath.mkdirs();
}
FileInputStream input = new FileInputStream(source);
FileOutputStream output = new FileOutputStream(target);
byte[] bufferarray = new byte[1024 * 64];
int prereadlength;
while ((prereadlength = input.read(bufferarray)) != -1) {
output.write(bufferarray, 0, prereadlength);
}
output.flush();
output.close();
input.close();
System.out.println("复制完毕!");
return true;
}
此方法仅能够实现单个文件的复制,如果要复制整个文件夹及旗下的所有文件,在《【Java】利用文件输入输出流完成把一个文件夹内的所有文件拷贝的另一的文件夹的操作》(
点击打开链接)一文中已经说过了,这里不再赘述,需要实现递归调用,如果单独地使用这个方法复制整个文件夹及旗下的所有文件是不行的,系统会报错。
下面介绍一种在新的JDK中,使用文件通道的方式复制单个文件的方法,代码如下:
/**
* 使用文件通道的方式复制文件
*
* @param soutrce
* 源文件
* @param target
* 复制到的新文件
*/
public static boolean fileChannelCopy(File source, File target) {
if(!source.exists()){
System.out.println("源文件不存在!");
return false;
}
File targetPath = new File(target.getParent());
if(!targetPath.exists()){
targetPath.mkdirs();
}
try {
FileInputStream fileInputStream = new FileInputStream(source);
FileOutputStream fileOutputStream = new FileOutputStream(target);
FileChannel fileChannelIn = fileInputStream.getChannel();// 得到对应的文件通道
FileChannel fileChannelOut = fileOutputStream.getChannel();// 得到对应的文件通道
fileChannelIn.transferTo(0, fileChannelIn.size(), fileChannelOut);// 连接两个通道,并且从in通道读取,然后写入out通道
// 人走带门
fileInputStream.close();
fileChannelIn.close();
fileOutputStream.close();
fileChannelOut.close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("复制完毕!");
return true;
}
如果在f:\存在一个1.txt,在主函数调用以上的方法如下:
public static void main(String[] args) throws Exception {
File source = new File("f:\\1.txt");
File target = new File("f:\\1\\aa.txt");
fileChannelCopy(source, target);
}
则有如下的运行效果,可以看到成功把f:\1.txt拷贝到f:\1\aa.txt。
这种文件通道的方法比旧方式快三倍以上,如果需要拷贝整个文件夹及旗下的所有文件,可以参考《【Java】利用文件输入输出流完成把一个文件夹内的所有文件拷贝的另一的文件夹的操作》(点击打开链接)中的方法进行改进。
同时可以看到,以上两个拷贝文件的方法,都需要注意的是,如果目标文件夹不存在,无论是老式的文件流还是新式的文件通道,都会出错的。
因此拷贝之前,先要判断目标文件夹是否存在,不存在,则需要新建一个。