您的位置:首页 > 编程语言 > Java开发

Java IO进行文件copy

2017-08-16 11:14 246 查看
此处列举四种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通道方式最快。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: