Mục lục
Copy file là một trong những nhu cầu phổ biến trong lập trình nói chung và Java nói riêng. Thế nhưng trong java.io.File class lại không hề cung cấp một method nào cho phép sao chép một file nguồn đến file đích một cách nhanh chóng. Vì vậy, trong bài viết này chúng ta sẽ cùng nhau tìm hiểu một số cách để sao chép file trong Java.
Copy file sử dụng Stream
Đây là cách thông thường để sao chép file trong java. Ở đây chúng ta tạo hai file – nguồn và đích. Sau đó, tạo InputStream từ nguồn và ghi nó vào tệp đích bằng OutputStream.
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(); } }
Copy file sử dụng FileChannel
Các class trong Java NIO đã được giới thiệu trong Java 1.4 và FileChannel có thể được sử dụng để sao chép tệp trong java một cách nhanh chóng thông qua transferFrom() method.
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(); } }
Copy file sử dụng Apache Commons IO FileUtils
Apache commons IO FileUtils.copyFile(File srcFile, File destFile) có thể được sử dụng để copy file trong Java. Nếu bạn đang sử dụng Apache Commons IO trong dự án của mình, bạn nên sử dụng nó để đơn giản hóa mã. Bên trong nó sử dụng Java NIO FileChannel, vì vậy nếu không sử dụng Apache commons thì các bạn có thể viết thuần như cách trên.
private static void copyFileUsingApacheCommonsIO(File source, File dest) throws IOException { FileUtils.copyFile(source, dest); }
Copy file sử dụng Files class
Nếu bạn đang sử dụng phiên bản Java 7 hoặc cao hơn, bạn có thể sử dụng Files.copy() method để copy file
private static void copyFileUsingJava7Files(File source, File dest) throws IOException { Files.copy(source.toPath(), dest.toPath()); }
Để tìm ra đâu là cách copy file nhanh nhất, chúng ta sẽ tiến hành một thử nghiệm sao chép file có kích thước 1GB.
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("./src/source.avi"); File dest = new File("./src/.avi"); // Sử dụng InputStream, OutputStream long start = System.nanoTime(); copyFileUsingStream(source, dest); System.out.println("Stream = "+(System.nanoTime()-start)); //Sử dụng FileChannel source = new File("./src/sourceChannel.avi"); dest = new File("./src/destChannel.avi"); start = System.nanoTime(); copyFileUsingChannel(source, dest); System.out.println("FileChannel = "+(System.nanoTime()-start)); //Sử dụng apache commons io source = new File("./src/sourceApache.avi"); dest = new File("./src//destApache.avi"); start = System.nanoTime(); copyFileUsingApacheCommonsIO(source, dest); System.out.println("Apache Commons IO = "+(System.nanoTime()-start)); // Sử dụng Files class - từ Java 7 trở đi source = new File("./src/sourceJava7.avi"); dest = new File("./src/destJava7.avi"); start = System.nanoTime(); copyFileUsingJava7Files(source, dest); System.out.println("Files = "+(System.nanoTime()-start)); } }
Output
Stream = 44582575000 FileChannel= 104138195000 Apache Commons IO = 108396714000 Files= 89061578000
Từ kết quả trên, rõ ràng rằng copy bằng InputStream, OutputStream là cách tốt nhất để sao chép file trong Java. Nhưng đó là một bài kiểm tra rất cơ bản. Nếu bạn đang làm việc trên một dự án chuyên sâu về hiệu suất, thì bạn nên thử các phương pháp khác nhau trên nhiều tập dữ liệu để tìm ra cách tốt nhất.
Nguồn
Java Copy File – 4 Ways to Copy File in Java