Java 複製文件 – Java 中複製文件的 4 種方法

Java 複製檔案是一個非常常見的操作。但是,java.io.File類別並沒有任何快捷方法可以將檔案從來源複製到目的地。在這裡,我們將學習四種不同的方法來在Java中複製檔案

Java 複製檔案

  1. Java 複製檔案 – 流

這是在Java中複製檔案的傳統方法。在這裡,我們創建兩個檔案 – 來源和目的地。然後,我們從來源創建InputStream,並使用OutputStream將其寫入目的地檔案,以進行Java複製檔案操作。這裡是使用流進行Java複製檔案的方法。

private 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 {
        is.close();
        os.close();
    }
}
  1. Java 複製檔案 – java.nio.channels.FileChannel

Java NIO 類別在Java 1.4中引入,可以使用FileChannel來複製檔案。根據transferFrom()方法的javadoc,這種複製檔案的方式應該比使用流更快。這裡是使用FileChannel複製檔案的方法。

private 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, sourceChannel.size());
       }finally{
           sourceChannel.close();
           destChannel.close();
   }
}
  1. Java 複製檔案 – Apache Commons IO FileUtils

Apache Commons IO的FileUtils.copyFile(File srcFile, File destFile)方法可以用于在Java中复制文件。如果您已经在项目中使用了Apache Commons IO,那么使用这个方法可以简化代码。它内部使用Java NIO的FileChannel,因此如果您没有在其他功能中使用它,可以避免使用这个包装方法。下面是使用Apache Commons IO进行Java文件复制操作的方法。

private static void copyFileUsingApacheCommonsIO(File source, File dest) throws IOException {
    FileUtils.copyFile(source, dest);
}
  1. Java复制文件 – Files类

如果您正在使用Java 7或更高版本,可以使用Files类的copy()方法来复制文件。它使用文件系统提供程序来复制文件。

private static void copyFileUsingJava7Files(File source, File dest) throws IOException {
    Files.copy(source.toPath(), dest.toPath());
}

现在,为了找出哪种方法最快,我编写了一个测试类,并逐个执行上述方法来复制1GB的文件。在每次调用中,我使用不同的文件来避免后续方法因为缓存而获得任何好处。

package com.journaldev.files;

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 JavaCopyFile {

    public static void main(String[] args) throws InterruptedException, IOException {
        File source = new File("/Users/pankaj/tmp/source.avi");
        File dest = new File("/Users/pankaj/tmp/dest.avi");

        //使用流的传统方式复制文件
        long start = System.nanoTime();
        copyFileUsingStream(source, dest);
        System.out.println("Time taken by Stream Copy = "+(System.nanoTime()-start));
        
        //使用java.nio的FileChannel复制文件
        source = new File("/Users/pankaj/tmp/sourceChannel.avi");
        dest = new File("/Users/pankaj/tmp/destChannel.avi");
        start = System.nanoTime();
        copyFileUsingChannel(source, dest);
        System.out.println("Time taken by Channel Copy = "+(System.nanoTime()-start));
        
        //使用apache commons io复制文件
        source = new File("/Users/pankaj/tmp/sourceApache.avi");
        dest = new File("/Users/pankaj/tmp/destApache.avi");
        start = System.nanoTime();
        copyFileUsingApacheCommonsIO(source, dest);
        System.out.println("Time taken by Apache Commons IO Copy = "+(System.nanoTime()-start));
        
        //使用Java 7的Files类
        source = new File("/Users/pankaj/tmp/sourceJava7.avi");
        dest = new File("/Users/pankaj/tmp/destJava7.avi");
        start = System.nanoTime();
        copyFileUsingJava7Files(source, dest);
        System.out.println("Time taken by Java7 Files Copy = "+(System.nanoTime()-start));        
    }
}

以下是上述程序的输出,请注意,我已经注释掉了上面的代码,以确保每次只使用一种方法进行java文件复制操作。

Time taken by Stream Copy = 44582575000
Time taken by Channel Copy = 104138195000
Time taken by Apache Commons IO Copy = 108396714000
Time taken by Java7 Files Copy = 89061578000

從輸出中可以清楚地看出,Stream Copy 是在 Java 中複製文件的最佳方式。但這只是一個非常基本的測試。如果您正在從事性能密集型項目,那麼您應該嘗試不同的方法來複製 Java 文件並記錄時間,以找出您項目的最佳方法。您還應根據文件的平均大小玩弄不同的 Java 文件複製方式。我已經在 YouTube 上創建了一個關於在 Java 中複製文件的 4 種方式的視頻,您可以觀看它以獲取更多信息。 https://www.youtube.com/watch?v=op6tgG95zek

Source:
https://www.digitalocean.com/community/tutorials/java-copy-file