Java 複製檔案的方式

方法一: 使用 java.io 的 FileInputStream 讀取,在使用 FileOutputStream 寫入。這種方式使用 byte stream 直接讀取來源檔案內容,在寫入到目標檔案。比 Files.copy 慢。

1
2
3
4
5
6
7
8
9
FileInputStream fis = new FileInputStream("source.txt");
FileOutputStream fos = new FileOutputStream("destination.txt");
byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer)) > 0) {
fos.write(buffer, 0, length);
}
fis.close();
fos.close();

方法二: 使用 java.nio 的 transferTo 讀取,在使用 transferFrom 寫入。這種方式可以直接在 FileChannel 中傳輸資料。它可以快速的將資料從一個 channel 傳輸到另外一個 channel ,而不需要在 User space 與 Kernal space 進行資料複製,是一種實現 zero copy 的複製方式。但是在某些作業系統中, transferTo 可能會限制傳輸的最大 Byte ,因此在使用時,可能需要進行分段傳輸。

1
2
3
4
5
FileChannel sourceChannel = new FileInputStream("source.txt").getChannel();
FileChannel destChannel = new FileOutputStream("destination.txt").getChannel();
sourceChannel.transferTo(0, sourceChannel.size(), destChannel);
sourceChannel.close();
destChannel.close();

方法三: 使用 java.nio 的 Files.copy 。java NIO 提供的一種高級操作方式,但是它本身不實現 zero copy 技術

1
2
3
Path sourcePath = Paths.get("source.txt");
Path destinationPath = Paths.get("destination.txt");
Files.copy(sourcePath, destinationPath, StandardCopyOption.REPLACE_EXISTING);

注意:以上的操作都沒有使用 try finally 或是 try-with-resources 關閉資源,正確的使用需要關閉資源才不會造成 Memory leak

1
2
3
4
5
6
7
8
9
10
try (FileInputStream fis = new FileInputStream("source.txt");
FileOutputStream fos = new FileOutputStream("destination.txt")) {
byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer)) > 0) {
fos.write(buffer, 0, length);
}
} catch (IOException e) {
e.printStackTrace();
}

評論