Copy file trong Java

Trong bài viết này, chúng ta đi tìm hiểu các cách copy file trong Java. Chúng ta có thể sử dụng File, FileInputStream, FileOutputStream, FileChannel, and Files. Ngoài ra, chúng ta có thể sử dụng thư viện third-party: Apache Commons IO và Google Guava.

Sử dụng FileInputStream và FileOutputStream

Chúng ta tạo luồng cho đọc và ghi file với FileInputStream và FileOutputStream. Khi không tìm thấy file, exception được report. File mô tả file hoặc đường dẫn trong Java.

CopyFileStream.java

package net.vncoding;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class CopyFileStream {

    public static void main(String[] args) throws IOException {

        File source = new File("src/resources/sample.txt");
        File dest = new File("src/resources/sample2.txt");

        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 {

            if (is != null) {
                is.close();
            }

            if (os != null) {
                os.close();
            }
        }
    }
}

Giải thích:
Ví dụ này mô tả cách copy file cổ điển bằng việc sử dụng FileInputStream, FileOutputStream, và File.

File source = new File("src/resources/sample.txt");
File dest = new File("src/resources/sample2.txt");

Đường dẫn cho file nguồn và file đích.

is = new FileInputStream(source);
os = new FileOutputStream(dest);

Tạo instance của class FileInputStream và FileOutputStream.

byte[] buffer = new byte[1024];

Cấp phát 1024 byte để chứa nội dung đọc từ file.

while ((length = is.read(buffer)) > 0) {

Phương thức đọc read() đọc số byte từ luồng input và lưu vào mảng buffer. Phương thức này trả về tổng số byte đọc được, hoặc trả về -1 nếu file rỗng.

os.write(buffer, 0, length);

Phương thức write() ghi byte dữ liệu được lưu mảng buffer ra luồng output. Tham số thứ nhất là data trong buffer, tham số thứ 2 là byte offset trong data (bạn muốn ghi từ byte thứ mấy) và tham số cuối là số lượng byte cần ghi.

Kết quả:
Nếu không có file sample.txt trong đường dẫn, exception xuất hiện. Error message sau sẽ xuất hiện trên màn hình console.
Exception in thread “main” java.io.FileNotFoundException: src\resources\sample.txt (The system cannot find the path specified)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(Unknown Source)
at java.io.FileInputStream.(Unknown Source)
at net.vncoding.CopyFileStream.main(CopyFileStream.java:22)

Giả sử tồn tại file sample.txt có nội dung:
one, two, three, four, five, six, seven, eight, nine, ten

Chương trình tạo ra file sample2.txt có nội dung y hệt file sample.txt

Sử dụng FileChannel

FileChannel là 1 kênh cho việc đọc, ghi, mapping và xử lí file. FileChannel là cách thay thế cho cách cổ điển sử dụng IO stream. FileChannel nằm trong package java.nio

CopyFileChannel.java

package net.vncoding;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;

public class CopyFileChannel {

    public static void main(String[] args) throws IOException {

        File source = new File("src/resources/sample.txt");
        File dest = new File("src/resources/sample2.txt");

        FileChannel sc = null;
        FileChannel dc = null;
        
        try {
            
            sc = new FileInputStream(source).getChannel();
            dc = new FileOutputStream(dest).getChannel();
            dc.transferFrom(sc, 0, sc.size());
            
            sc.close();
            dc.close();
            
        } finally {
            
            if (sc != null) {
                sc.close();
            }

            if (dc != null) {
                dc.close();
            }
        }
    }
}

Giải thích:

sc = new FileInputStream(source).getChannel();

Kênh nguồn được tạo từ FileInputStream với phương thức getChannel().

dc.transferFrom(sc, 0, sc.size());

Phương thức transferFrom() biến đổi byte từ kênh ngồn vào kênh đích. Tham số thứ nhất là kênh nguồn, tham số thứ 2 là vị trí bắt đầu cho việc biến đổi trong file và tham số cuối là số byte cần biến đổi.

Kết quả:
File sample2.txt được tạo ra với nội dung giống với file sample.txt

Sử dụng Files.copy

Java 7 giới thiệu phương thức Files.copy(), cách này rất đơn giản. Việc copy file fail nếu file đích đã tồn tại, nếu chúng ta chỉ định tùy chọn REPLACE_EXISTING, file đích mới sẽ overwrite file cũ. Phương thức Files.copy() nhận tham số thứ 3 với các hằng số như sau:

REPLACE_EXISTING – nếu tồn tại file giống tên với file đích, file đích được tạo ra, thay thế cho file cũ.
COPY_ATTRIBUTES – copy thuộc tính file nguồn cho file đích.
ATOMIC_MOVE – move file
NOFOLLOW_LINKS – symbolic links are not followed.
3 hằng số đầu tiên được define trong StandarCopyOption, NOFOLLOW_LINKS được define trong LinkOption.

CopyFileJava7.java

package net.vncoding;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;

public class CopyFileJava7 {

    public static void main(String[] args) throws IOException {

        File source = new File("src/resources/sample.txt");
        File dest = new File("src/resources/sample2.txt");

        Files.copy(source.toPath(), dest.toPath(), StandardCopyOption.REPLACE_EXISTING);
    }
}

Giải thích:
File sample2.txt được tạo ra với nội dung giống file sample.txt.
Nếu file sample2.txt đã tồn tại, file sample2.txt thay thế file cũ.

Sử dụng Apache Commons IO

CopyFileApacheCommons.java

package net.vncoding;

import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;

public class CopyFileApacheCommons {
    
    public static void main(String[] args) throws IOException {
        
        File source = new File("src/resources/sample.txt");
        File dest = new File("src/resources/sample2.txt");        
        
        FileUtils.copyFile(source, dest);
    }
}

Giải thích:
Copy file sử dụng phương thức copyFile() của thư viện Apache Commons IO.

Sử dụng Google Guava

Trong ví dụ này, chúng ta sử dụng open-source Google Guava được dùng cho Java. Nó có phương thức Files.copy() để copy file.

package net.vncoding;

import com.google.common.io.Files;
import java.io.File;
import java.io.IOException;

public class CopyFileGuava {

    public static void main(String[] args) throws IOException {

        File source = new File("src/resources/sample.txt");
        File dest = new File("src/resources/sample2.txt");

        Files.copy(source, dest);
    }
}

Giải thích:
Để sử dụng Google Guava, chúng ta download tại đây, và add external JAR cho project.

Be the first to comment

Leave a Reply