Javaでファイルをコピーする方法 – Javaでファイルをコピーする4つの方法

Javaファイルコピーは非常に一般的な操作ですが、java.io.Fileクラスにはファイルをソースから宛先にコピーするためのショートカットメソッドはありません。ここでは、Javaでファイルをコピーするための4つの異なる方法について学びます。

Javaファイルコピー

  1. Javaファイルコピー – ストリーム

これはJavaでのファイルコピーの従来の方法です。ソースと宛先の2つのファイルを作成し、ソースからInputStreamを作成し、Javaファイルコピー操作のためにOutputStreamを使用して宛先ファイルに書き込みます。ストリームを使用した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を使用してJavaでファイルをコピーすることができます。 transferFrom()メソッドのjavadocによると、この方法はJavaファイルコピーにおいてストリームを使用するよりも高速であるとされています。ファイルをコピーするために使用できるメソッドは次のとおりです。

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を使用しているため、他の機能でそれをすでに使用していない場合は、このラッパーメソッドを回避することができます。ここでは、Javaのファイルコピー操作にApache Commons IOを使用するためのメソッドが示されています。

private static void copyFileUsingApacheCommonsIO(File source, File dest) throws IOException {
    FileUtils.copyFile(source, dest);
}
  1. Javaファイルのコピー-Filesクラス

Java 7以降で作業している場合は、Filesクラスのcopy()メソッドを使用してJavaでファイルをコピーすることができます。これはファイルシステムプロバイダを使用してファイルをコピーします。

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

次に、最も速いメソッドを見つけるために、テストクラスを作成し、上記のメソッドを1つずつ実行して1 GBのファイルをコピーしました。各呼び出しでは、キャッシュの恩恵を後のメソッドに与えないように、異なるファイルを使用しました。

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ファイルのコピー操作に1つのメソッドのみが使用されることを確認しています。

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でファイルをコピーしてみることもおすすめです。Javaでファイルをコピーする方法について、4つの方法のYouTubeビデオを作成しましたので、ぜひご覧ください。https://www.youtube.com/watch?v=op6tgG95zek

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