文章目錄
- 一、Java文件拷貝的5種方式
- 1. 傳統IO流(字節流/字符流)手動拷貝
- 2. NIO的`FileChannel`拷貝(`transferTo`/`transferFrom`)
- 3. Java 7+的`Files.copy()`工具類
- 4. 緩沖流(`BufferedInputStream`/`BufferedOutputStream`)
- 5. 第三方庫(如Apache Commons IO)
- 二、效率對比與結論
- 各方式效率排序(從高到低):
- 為什么`FileChannel`效率最高?
- 注意事項:
- 總結
在Java中,文件拷貝是常見的IO操作,主要有以下幾種實現方式,它們的效率因底層機制不同而有顯著差異:
一、Java文件拷貝的5種方式
1. 傳統IO流(字節流/字符流)手動拷貝
通過
FileInputStream
和FileOutputStream
逐字節或按緩沖區讀取寫入,是最基礎的方式。
public static void copyWithStream(File source, File dest) throws IOException {try (InputStream in = new FileInputStream(source);OutputStream out = new FileOutputStream(dest)) {byte[] buffer = new byte[8192]; // 8KB緩沖區int bytesRead;while ((bytesRead = in.read(buffer)) != -1) {out.write(buffer, 0, bytesRead);}}
}
2. NIO的FileChannel
拷貝(transferTo
/transferFrom
)
基于NIO的通道(Channel)機制,通過
FileChannel
的transferTo
或transferFrom
方法實現拷貝,底層依賴操作系統的零拷貝(Zero-Copy)機制。
public static void copyWithChannel(File source, File dest) throws IOException {try (FileChannel inChannel = new FileInputStream(source).getChannel();FileChannel outChannel = new FileOutputStream(dest).getChannel()) {inChannel.transferTo(0, inChannel.size(), outChannel);}
}
3. Java 7+的Files.copy()
工具類
Java 7引入的
java.nio.file.Files
工具類,封裝了拷貝邏輯,內部實際使用FileChannel
實現。
public static void copyWithFiles(File source, File dest) throws IOException {Files.copy(source.toPath(), dest.toPath());
}
4. 緩沖流(BufferedInputStream
/BufferedOutputStream
)
在傳統字節流基礎上增加緩沖區,減少IO次數(默認8KB緩沖區,可自定義大小)。
public static void copyWithBufferedStream(File source, File dest) throws IOException {try (BufferedInputStream in = new BufferedInputStream(new FileInputStream(source));BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(dest))) {byte[] buffer = new byte[8192];int bytesRead;while ((bytesRead = in.read(buffer)) != -1) {out.write(buffer, 0, bytesRead);}}
}
5. 第三方庫(如Apache Commons IO)
借助第三方工具類(如
FileUtils.copyFile
),內部實現類似緩沖流,但簡化了代碼。
public static void copyWithCommonsIO(File source, File dest) throws IOException {FileUtils.copyFile(source, dest); // 需要引入commons-io依賴
}
二、效率對比與結論
各方式效率排序(從高到低):
- NIO
FileChannel
(transferTo
/transferFrom
)Files.copy()
(內部基于FileChannel
,效率接近)- 緩沖流(
BufferedInputStream
/BufferedOutputStream
)- 第三方庫(如Apache Commons IO)(與緩沖流效率相當)
- 傳統字節流手動拷貝(無緩沖,效率最低)
為什么FileChannel
效率最高?
- 零拷貝(Zero-Copy)機制:
transferTo
方法直接在操作系統內核空間完成數據傳輸,避免了Java堆內存與內核緩沖區之間的來回拷貝(用戶態→內核態的切換減少)。- 減少IO次數:傳統流需要多次系統調用(read→用戶態→write→內核態),而
FileChannel
通過一次系統調用完成數據傳輸,尤其對大文件(GB級)優勢明顯。
注意事項:
- 小文件場景:各方式效率差異不大,
Files.copy()
因代碼簡潔更推薦。- 大文件場景:
FileChannel
的優勢顯著,拷貝速度可能是傳統流的2-10倍。- 跨文件系統拷貝:若源文件和目標文件在不同文件系統,
transferTo
可能無法一次完成,需循環調用,但仍比傳統流高效。
總結
效率最高的方式是使用NIO的
FileChannel.transferTo()
或transferFrom()
,尤其適合大文件拷貝。日常開發中,推薦使用Files.copy()
(Java 7+),它兼顧了效率與代碼簡潔性,底層同樣依賴FileChannel
的零拷貝機制。