4种复制文件的方式性能比较
最近工作中涉及到了文件的下载,于是就想寻找一种最快的方式,考虑到在不考虑网络因素的情况下,下载和文件的复制其实可以理解为
一回事,本次测试中使用了4种方式
硬件如下
jdk 7
代码如下:
public class FileDownloader {
public static void copyFileUsingStream(File source, File dest) throws IOException {
InputStream is = null;
OutputStream os = null;
try {
is = new FileInputStream(source);
os = new FileOutputStream(dest);
byte[] buffer = new byte[1024];
int length;
while ((length = is.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
} finally {
IOUtils.closeQuietly(is);
IOUtils.closeQuietly(os);
}
}
public static void copyFileUsingApacheCommonsIO(File source, File dest) throws IOException {
FileUtils.copyFile(source, dest);
}
public static void copyFileUsingJava7Files(File source, File dest) throws IOException {
Files.copy(source.toPath(), dest.toPath());
}
public static void copyFileUsingChannel(File source, File dest) throws IOException {
FileChannel sourceChannel = null;
FileChannel destChannel = null;
try {
sourceChannel = new FileInputStream(source).getChannel();
destChannel = new FileOutputStream(dest).getChannel();
destChannel.transferFrom(sourceChannel, 0, Long.MAX_VALUE);
} finally {
IOUtils.closeQuietly(sourceChannel);
IOUtils.closeQuietly(destChannel);
}
}
}
测试代码如下:
public class FileDownloaderTest {
private File source;
private File dest;
@Test
public void testCopyFileUsingStream() throws Exception {
source = new File("e://1.avi");
dest = new File("d://1.avi");
long start = System.nanoTime();
FileDownloader.copyFileUsingStream(source, dest);
System.out.println("Time taken by Stream Copy = " + (System.nanoTime() - start));
}
@Test
public void testCopyFileUsingApacheCommonsIO() throws Exception {
source = new File("e://2.avi");
dest = new File("d://2.avi");
long start = System.nanoTime();
FileDownloader.copyFileUsingApacheCommonsIO(source, dest);
System.out.println("Time taken by Apache Commons IO Copy = " + (System.nanoTime() - start));
}
@Test
public void testCopyFileUsingJava7Files() throws Exception {
source = new File("e://3.avi");
dest = new File("d://3.avi");
long start = System.nanoTime();
FileDownloader.copyFileUsingJava7Files(source, dest);
System.out.println("Time taken by Java7 Files Copy = " + (System.nanoTime() - start));
}
@Test
public void testCopyFileUsingChannel() throws Exception {
source = new File("e://4.avi");
dest = new File("d://4.avi");
long start = System.nanoTime();
FileDownloader.copyFileUsingChannel(source, dest);
System.out.println("Time taken by Channel Copy = " + (System.nanoTime() - start));
}
}
测试方法:
将同样的文件,在原始目录下,复制4份,文件名不同,文件一摸一样。然后多次执行测试代码。
做了2组测试,每组执行了3次,结果如下:
文件大小:98.3M
Time taken by Apache Commons IO Copy = 64954135
Time taken by Stream Copy = 375539829
Time taken by Channel Copy = 57012898
Time taken by Java7 Files Copy = 65101591
Time taken by Apache Commons IO Copy = 63818085
Time taken by Stream Copy = 375973711
Time taken by Channel Copy = 57417522
Time taken by Java7 Files Copy = 65688487
Time taken by Apache Commons IO Copy = 63172674
Time taken by Stream Copy = 354136258
Time taken by Channel Copy = 58497984
Time taken by Java7 Files Copy = 79916185
文件大小:746M
Time taken by Apache Commons IO Copy = 660830180
Time taken by Stream Copy = 2791359285
Time taken by Channel Copy = 3861113037
Time taken by Java7 Files Copy = 6162249000
Time taken by Apache Commons IO Copy = 381343255
Time taken by Channel Copy = 2987676936
Time taken by Stream Copy = 2856878081
Time taken by Java7 Files Copy = 19034765260
Time taken by Apache Commons IO Copy = 419664709
Time taken by Stream Copy = 2761465029
Time taken by Channel Copy = 4183763748
Time taken by Java7 Files Copy = 23261100925
结论 nio 方式比较快