文件系統操作是 Java 開發中高頻需求。本文提供生產級工具類,實現兩大核心功能:目錄結構完整遞歸複製、多文本文件合併為單一文件。代碼採用流式處理,記憶體佔用穩定,支援大文件場景。
copyFiles 方法採用深度優先遞歸策略,完整保留目錄層級結構。針對文件採用 1KB 緩衝區流式讀寫,針對目錄自動創建對應子目錄並繼續遞歸。
/**
* 拷貝某個文件目錄下的所有文件與子目錄
* @param sourceFile 源文件/目錄
* @param desFile 目標目錄
*/
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 targetDir = new File(desFile.getPath() + "/" + sourceFile.getName());
if (!targetDir.exists()) targetDir.mkdir();
String[] names = sourceFile.list();
if (names != null) {
for (String name : names) {
copyFiles(new File(sourceFile.getPath() + "/" + name), targetDir);
}
}
}
}
mergeFile 方法遞歸遍歷源目錄,將所有非目錄文件內容順序追加寫入目標文件。採用追加模式 (FileOutputStream 第二參數 true) 實現多文件內容串聯。
/**
* 將目錄下所有文本文件合併到單一文件
* @param sourceFile 源目錄
* @param decFile 目標合併文件
* @return 目標文件引用
*/
private static File mergeFile(File sourceFile, File decFile) throws IOException {
String[] fileList = sourceFile.list();
if (fileList != null) {
for (String fileName : fileList) {
File file = new File(sourceFile.getPath() + "/" + fileName);
if (!file.isDirectory()) {
try (FileInputStream fis = new FileInputStream(file);
FileOutputStream fos = new FileOutputStream(decFile, 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;
}
展示兩種功能的實際調用方式,路徑參數請根據實際環境修改。
public static void main(String[] args) {
try {
// 合併文件示例(註釋掉)
// mergeFile(new File("C:/source_dir"), new File("D:/all.sql"));
// 目錄複製示例
copyFiles(new File("G:/學習資料/筆記"), new File("G:/Test"));
} catch (IOException e) {
e.printStackTrace();
}
}
| 技術點 | 實現方式 | 優勢 |
|---|---|---|
| 遞歸遍歷 | File.list() + isDirectory() 判斷 | 簡潔處理任意深度目錄結構 |
| 流式讀寫 | 1024 字節緩衝區 + while 循環 | 恆定記憶體佔用,支援超大文件 |
| 資源管理 | try-with-resources (JDK 7+) | 自動關閉流,防止資源洩漏 |
| 追加寫入 | FileOutputStream(file, true) | 無需載入全文即可合併多文件 |
| 路徑拼接 | 手動拼接 + File.separator 建議 | 跨平台相容性更好 |