Java IO进行文件copy
程序员文章站
2022-06-16 20:06:17
...
此处列举四种copy方式(不考虑复制时重复的冲突),其中前三种需要递归复制,第四种使用ApacheCommonsIO工具类,不需要自己手写递归。
递归复制
/**
* 递归复制
* @param file 原文件路径
* @param copyFile 复制文件路径
* @param type 复制方式
* @throws IOException
*/
public static void copy(File file, File copyFile, int type) throws IOException {
if (file.isDirectory()) {
if (!copyFile.exists()) {
copyFile.mkdir();
}
File[] fileList = file.listFiles();
for (File file1 : fileList) {
copy(file1,new File(copyFile.getPath()+File.separator+file1.getName()),type);
}
} else {
switch (type) {
case 1:
one(file, copyFile);
break;
case 2:
two(file, copyFile);
break;
case 3:
Files.copy(file.toPath(),copyFile.toPath());
break;
}
}
}
方式一:传统流复制(需递归调用)
public static void one(File file, File copyFile) throws IOException {
FileInputStream src = new FileInputStream(file);
FileOutputStream desc = new FileOutputStream(copyFile);
byte[] buf = new byte[1024 * 10];
int len = -1;
while ((len = src.read(buf)) != -1) {
desc.write(buf, 0, len);
}
src.close();
desc.close();
}
方式二:Channel通道方式(需递归调用)
public static void two(File file, File copyFile) throws IOException {
FileInputStream fis = new FileInputStream(file);
FileOutputStream fos = new FileOutputStream(copyFile);
FileChannel in = fis.getChannel();
FileChannel out = fos.getChannel();
in.transferTo(0,in.size(),out);
in.close();
out.close();
src.close();
desc.close();
}
方式三:NIO的Files.copy方法(需递归调用)
Files.copy(file.toPath(),copyFile.toPath());
方式四:ApacheCommonsIO工具类(一句代码直接搞定,很省事)
FileUtils.copyDirectory(file4,copyFile4);
下面是完整代码,此处使用了四个相同文件分别复制,用来测试每个复制所用耗时。测试文件为项目源代码,大概5000+文件,大小60M左右。
package com.mosen;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
/**
* Created by Mosen on 2017/8/15.
*/
public class Copy {
public static void main(String[] args) throws IOException {
File file1 = new File("C:\\Users\\Mosen\\Desktop\\copyTest\\FileTest1");
File copyFile1 = new File("C:\\Users\\Mosen\\Desktop\\copyTest\\FileTestCopy1");
long start = System.currentTimeMillis();
copy(file1,copyFile1,1); //方式1,传统方式
long end = System.currentTimeMillis();
System.out.println("方式1复制完毕!耗时:" + (end - start) + "ms");
File file2 = new File("C:\\Users\\Mosen\\Desktop\\copyTest\\FileTest2");
File copyFile2 = new File("C:\\Users\\Mosen\\Desktop\\copyTest\\FileTestCopy2");
start = System.currentTimeMillis();
copy(file2,copyFile2,2); //方式2,Channel通道方式
end = System.currentTimeMillis();
System.out.println("方式2复制完毕!耗时:" + (end - start) + "ms");
File file3 = new File("C:\\Users\\Mosen\\Desktop\\copyTest\\FileTest3");
File copyFile3 = new File("C:\\Users\\Mosen\\Desktop\\copyTest\\FileTestCopy3");
start = System.currentTimeMillis();
copy(file3,copyFile3,3); //方式3,NIO的Files.copy方式
end = System.currentTimeMillis();
System.out.println("方式3复制完毕!耗时:" + (end - start) + "ms");
File file4 = new File("C:\\Users\\Mosen\\Desktop\\copyTest\\FileTest4");
File copyFile4 = new File("C:\\Users\\Mosen\\Desktop\\copyTest\\FileTestCopy4");
start = System.currentTimeMillis();
FileUtils.copyDirectory(file4,copyFile4);
end = System.currentTimeMillis(); //方式4,Apache Commons 工具类的方式
System.out.println("方式4复制完毕!耗时:" + (end - start) + "ms");
}
/**
* 递归复制
* @param file 原文件路径
* @param copyFile 复制文件路径
* @param type 复制方式
* @throws IOException
*/
public static void copy(File file, File copyFile, int type) throws IOException {
if (file.isDirectory()) {
if (!copyFile.exists()) {
copyFile.mkdir();
}
File[] fileList = file.listFiles();
for (File file1 : fileList) {
copy(file1,new File(copyFile.getPath()+File.separator+file1.getName()),type);
}
} else {
switch (type) {
case 1:
one(file, copyFile);
break;
case 2:
two(file, copyFile);
break;
case 3:
Files.copy(file.toPath(),copyFile.toPath());
break;
}
}
}
/**
* 传统方式复制(文件,非文件夹)
* @param file 原文件路径
* @param copyFile 复制文件路径
* @throws IOException
*/
public static void one(File file, File copyFile) throws IOException {
FileInputStream src = new FileInputStream(file);
FileOutputStream desc = new FileOutputStream(copyFile);
byte[] buf = new byte[1024 * 10];
int len = -1;
while ((len = src.read(buf)) != -1) {
desc.write(buf, 0, len);
}
src.close();
desc.close();
}
/**
* 通道方式复制(文件,非文件夹)
* @param file 原文件路径
* @param copyFile 复制文件路径
* @throws IOException
*/
public static void two(File file, File copyFile) throws IOException {
FileInputStream src = new FileInputStream(file);
FileOutputStream desc = new FileOutputStream(copyFile);
//通道方式
FileChannel in = src.getChannel();
FileChannel out = desc.getChannel();
in.transferTo(0,in.size(),out);
in.close();
out.close();
src.close();
desc.close();
}
}
测试结果
方式1复制完毕!耗时:18067ms //传统流方式
方式2复制完毕!耗时:12856ms //channel通道方式
方式3复制完毕!耗时:17840ms //NIO的Files.copy方式
方式4复制完毕!耗时:23773ms //ApacheCommonsIO工具类方式
在Windows上直接拖拽复制大约20s左右。
总的来说,复制还是channel通道方式最快。