尽管Java提供了java.io.File类,可以处理一些文件操作,但是没有复制文件的方法。
但你的程序需要操作文件的相关信息时,复制的操作是挺重要的。这里提供了几种复制文件的方法。
- 使用FileStreams
这是最普遍的复制文件内容到另外一个文件的方法,它使用FileInputStream读取文件A,并使用FileOutputStream写入到文件B。
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
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(); } } |
此代码在比较大的文件上执行了多次的读、写操作,它的性能会比以下的方法差一些。
- 使用java.nio.channels.FileChannel
Java NIO 包含了一个 transferFrom 方法,依照文档可以看出,它可以比 FileStreams 执行更快的复制操作。
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
private static void copyFileUsingFileChannels(File source, File dest) throws IOException { FileChannel inputChannel = null; FileChannel outputChannel = null; FileInputStream fis = null; FileOutputStream fos = null; try { fis = new FileInputStream(source); fos = new FileOutputStream(dest); inputChannel = fis.getChannel(); outputChannel = fos.getChannel(); outputChannel.transferFrom(inputChannel, 0, inputChannel.size()); } finally { fis.close(); fos.close(); inputChannel.close(); outputChannel.close(); } } |
- 使用Apache Commons IO
Apache Commons IO 的 FileUtils 类提供了一个 copyFile(File srcFile, File destFile) 方法,可以复制一个文件到另外一个文件。当你的项目里面包含了Apache Commons FileUtils ,使用起来将非常方便。基本上,这个方法的内部也是使用了 Java NIO FileChannel 。
下面是第三种方法
1 2 3 4 |
private static void copyFileUsingJava7Files(File source, File dest) throws IOException { Files.copy(source.toPath(), dest.toPath()); } |
- 在java 7上使用Files类
1 2 3 4 |
private static void copyFileUsingApacheCommonsIO(File source, File dest) throws IOException { FileUtils.copyFile(source, dest); } |
测试
这里使用一个200多M的文件,使用上面4种方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
package com.jdk5.test.copy_file; 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("D:\\copy\\sourcefile1.txt"); File dest = new File("D:\\copy\\dest\\file1.txt"); // copy file using FileStreams long start = System.currentTimeMillis(); long end; copyFileUsingFileStreams(source, dest); System.out.println("Time taken by FileStreams Copy = \t" + (System.currentTimeMillis() - start)); // copy files using java.nio.FileChannel source = new File("D:\\copy\\sourcefile1.txt"); dest = new File("D:\\copy\\dest\\file2.txt"); start = System.currentTimeMillis(); copyFileUsingFileChannels(source, dest); end = System.currentTimeMillis(); System.out.println("Time taken by FileChannels Copy = \t" + (end - start)); // copy file using Java 7 Files class source = new File("D:\\copy\\sourcefile1.txt"); dest = new File("D:\\copy\\dest\\file3.txt"); start = System.currentTimeMillis(); copyFileUsingJava7Files(source, dest); end = System.currentTimeMillis(); System.out.println("Time taken by Java7 Files Copy = \t" + (end - start)); // copy files using apache commons io source = new File("D:\\copy\\sourcefile1.txt"); dest = new File("D:\\copy\\dest\\file4.txt"); start = System.currentTimeMillis(); copyFileUsingApacheCommonsIO(source, dest); end = System.currentTimeMillis(); System.out.println("Time taken by Apache Commons IO Copy = \t" + (end - start)); } } |
结果如下:
1 2 3 4 |
Time taken by FileStreams Copy = 1070 Time taken by FileChannels Copy = 147 Time taken by Java7 Files Copy = 835 Time taken by Apache Commons IO Copy = 1034 |
As you can see FileChannels is the best way to copy large files. If you work with even larger files you will notice a much bigger speed difference.
使用FileChannels的方法最快,当需要复制更大文件的时候,这4种方法的时间差会更明显