在日常開發中,經常需要處理目錄樹的複製,或是將分散的文本檔案合併為單一檔案。本文提供一個實用的 FileReaderUtil 工具類,涵蓋這兩大核心功能,程式碼簡潔且具備良好的錯誤處理機制。
package com.firewolf.test;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileReaderUtil {
public static void main(String[] args) {
try {
// 範例:合併檔案(註解掉)
// mergeFile(new File("C:/Documents and Settings/liuxing0/桌面/新建文件夾/script"), new File("D:/all.sql"));
// 範例:複製目錄
copyFiles(new File("G:/學習資料/筆記"), new File("G:/Test"));
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 遞歸複製檔案或目錄
* @param sourceFile 來源路徑
* @param desFile 目標路徑
* @throws IOException
*/
private static void copyFiles(File sourceFile, File desFile) throws IOException {
if (sourceFile.isFile()) {
// 處理單一檔案複製
File targetFile = new File(desFile.getPath() + "/" + sourceFile.getName());
try (FileInputStream fis = new FileInputStream(sourceFile);
FileOutputStream fos = new FileOutputStream(targetFile)) {
byte[] buf = new byte[1024];
int len;
while ((len = fis.read(buf)) != -1) {
fos.write(buf, 0, len);
}
}
} else {
// 處理目錄:建立對應目錄並遞歸處理子項
File dir = new File(desFile.getPath() + "/" + sourceFile.getName());
if (!dir.exists()) {
dir.mkdir();
}
String[] names = sourceFile.list();
if (names != null) {
for (String name : names) {
copyFiles(new File(sourceFile.getPath() + "/" + name), dir);
}
}
}
}
/**
* 遞歸合併目錄下所有文本檔案到單一檔案
* @param sourceFile 來源目錄
* @param decFile 目標合併檔案
* @return 目標檔案物件
* @throws IOException
*/
private static File mergeFile(File sourceFile, File decFile) throws IOException {
String[] fileList = sourceFile.list();
if (fileList == null) return decFile;
for (String name : fileList) {
File file = new File(sourceFile.getPath() + "/" + name);
if (!file.isDirectory()) {
// 合併檔案內容
try (FileInputStream fis = new FileInputStream(file);
FileOutputStream fos = new FileOutputStream(decFile, true)) { // true = 追加模式
byte[] buffer = new byte[1024];
int len;
while ((len = fis.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
}
} else {
// 遞歸處理子目錄
decFile = mergeFile(file, decFile);
}
}
return decFile;
}
}
程式碼使用 JDK 7+ 的 try-with-resources 語法,確保 FileInputStream 與 FileOutputStream 在正常或異常結束時自動關閉,避免資源洩漏。
採用 1024 位元組(1KB)緩衝區,在記憶體佔用與 I/O 效能之間取得平衡。大檔案場景可適當調大(如 8192)。
new FileOutputStream(decFile, true) 的第二個參數 true 開啟追加模式,使多個檔案內容順序寫入同一目標檔案。
sourceFile.list() 在目錄不存在或無權限時會回傳 null,程式碼加入非空判斷,增強健壯性。
本工具類展示了 Java I/O 流操作目錄樹的經典遞歸模式,程式碼結構清晰、異常處理完善,可直接整合到專案中作為檔案操作基礎組件。後續可擴充檔案過濾、進度回調、多執行緒並行複製等進階功能。