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