Java中把一個文件夾下的所有文件復(fù)制到另一個文件夾的完整實現(xiàn)方案
在Java中把一個文件夾下的所有文件復(fù)制到另一個文件夾(支持多級目錄、空文件夾、文件覆蓋等場景),以下是基于Java原生API的完整實現(xiàn)方案(兼容Java 8+,無需額外依賴):
一、核心實現(xiàn)思路
- 校驗源文件夾:確保源文件夾存在且是合法目錄;
- 創(chuàng)建目標文件夾:若目標文件夾不存在,自動遞歸創(chuàng)建(包括多級父目錄);
- 遞歸遍歷源文件:遍歷源文件夾下的所有文件/子目錄,區(qū)分文件和目錄分別處理;
- 復(fù)制文件:對文件使用字節(jié)流/通道復(fù)制,對目錄遞歸創(chuàng)建并復(fù)制其內(nèi)文件;
- 異常處理:捕獲IO異常,保證復(fù)制過程的健壯性。
二、完整可運行代碼
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
/**
* 文件夾復(fù)制工具類(支持多級目錄、文件覆蓋)
*/
public class FolderCopyUtil {
/**
* 核心方法:復(fù)制源文件夾下的所有文件/目錄到目標文件夾
* @param sourceDirPath 源文件夾路徑(如:D:/source)
* @param targetDirPath 目標文件夾路徑(如:D:/target)
* @throws IOException IO異常(文件無法讀取/寫入)
*/
public static void copyFolder(String sourceDirPath, String targetDirPath) throws IOException {
File sourceDir = new File(sourceDirPath);
File targetDir = new File(targetDirPath);
// 步驟1:校驗源文件夾合法性
if (!sourceDir.exists()) {
throw new IOException("源文件夾不存在:" + sourceDirPath);
}
if (!sourceDir.isDirectory()) {
throw new IOException("路徑不是合法文件夾:" + sourceDirPath);
}
// 步驟2:創(chuàng)建目標文件夾(遞歸創(chuàng)建多級目錄,已存在則無影響)
if (!targetDir.exists()) {
boolean isCreated = targetDir.mkdirs();
if (!isCreated) {
throw new IOException("目標文件夾創(chuàng)建失?。? + targetDirPath);
}
}
// 步驟3:遍歷源文件夾下的所有文件/子目錄
File[] files = sourceDir.listFiles();
if (files == null) { // 源文件夾為空或無讀取權(quán)限
return;
}
for (File file : files) {
String targetFilePath = targetDirPath + File.separator + file.getName();
if (file.isFile()) {
// 步驟4:復(fù)制文件(覆蓋已存在的目標文件)
copyFile(file, new File(targetFilePath));
System.out.println("文件復(fù)制成功:" + file.getPath() + " → " + targetFilePath);
} else if (file.isDirectory()) {
// 步驟5:遞歸復(fù)制子目錄
copyFolder(file.getPath(), targetFilePath);
System.out.println("目錄復(fù)制成功:" + file.getPath() + " → " + targetFilePath);
}
}
}
/**
* 輔助方法:復(fù)制單個文件(使用NIO FileChannel,效率更高)
* @param sourceFile 源文件
* @param targetFile 目標文件
* @throws IOException IO異常
*/
private static void copyFile(File sourceFile, File targetFile) throws IOException {
// 覆蓋目標文件(若已存在則刪除后重建)
if (targetFile.exists()) {
boolean isDeleted = targetFile.delete();
if (!isDeleted) {
throw new IOException("目標文件覆蓋失敗,無法刪除已有文件:" + targetFile.getPath());
}
}
// 使用NIO通道復(fù)制(比傳統(tǒng)字節(jié)流效率更高)
try (FileInputStream fis = new FileInputStream(sourceFile);
FileOutputStream fos = new FileOutputStream(targetFile);
FileChannel inChannel = fis.getChannel();
FileChannel outChannel = fos.getChannel()) {
// 批量傳輸字節(jié),避免逐字節(jié)復(fù)制,提升大文件復(fù)制效率
long transferred = 0;
long fileSize = inChannel.size();
while (transferred < fileSize) {
transferred += inChannel.transferTo(transferred, fileSize - transferred, outChannel);
}
}
}
// 測試方法
public static void main(String[] args) {
// 替換為你的源文件夾和目標文件夾路徑
String sourceDir = "D:/test/source";
String targetDir = "D:/test/target";
try {
copyFolder(sourceDir, targetDir);
System.out.println("文件夾復(fù)制完成!");
} catch (IOException e) {
System.err.println("文件夾復(fù)制失敗:" + e.getMessage());
e.printStackTrace();
}
}
}
三、關(guān)鍵細節(jié)說明
核心API解析
File.mkdirs():遞歸創(chuàng)建多級目錄(如目標路徑是D:/a/b/c,若a/b不存在,會自動創(chuàng)建),區(qū)別于mkdir()(僅創(chuàng)建單級目錄);FileChannel.transferTo():NIO通道復(fù)制文件,直接利用操作系統(tǒng)底層IO,比傳統(tǒng)InputStream/OutputStream逐字節(jié)復(fù)制效率高,尤其適合大文件;try-with-resources:自動關(guān)閉流/通道,避免手動關(guān)閉遺漏導(dǎo)致的資源泄露。
關(guān)鍵特性適配
- 覆蓋目標文件:復(fù)制前先刪除已存在的目標文件,確保復(fù)制的是最新文件;若需避免覆蓋,可在
copyFile方法中增加判斷:
if (targetFile.exists()) {
System.out.println("目標文件已存在,跳過復(fù)制:" + targetFile.getPath());
return;
}
- 空文件夾處理:源文件夾為空時,
listFiles()返回null,直接返回不報錯;目標空文件夾會正常創(chuàng)建; - 多級目錄復(fù)制:通過遞歸調(diào)用
copyFolder,支持復(fù)制源文件夾下的所有子目錄及文件; - 權(quán)限防護:若源文件無讀取權(quán)限/目標文件夾無寫入權(quán)限,會拋出
IOException并提示具體原因。
路徑兼容性
- 使用
File.separator代替硬編碼的/或\,兼容Windows(\)和Linux/Mac(/)系統(tǒng); - 支持絕對路徑(如
D:/test)和相對路徑(如./source)。
四、拓展:Java 7+ Files工具類實現(xiàn)(更簡潔)
若使用Java 7及以上版本,可借助java.nio.file.Files工具類簡化代碼,無需手動實現(xiàn)文件復(fù)制邏輯:
import java.io.IOException;
import java.nio.file.*;
public class FolderCopyWithFilesUtil {
public static void copyFolder(String sourceDirPath, String targetDirPath) throws IOException {
Path sourcePath = Paths.get(sourceDirPath);
Path targetPath = Paths.get(targetDirPath);
// 遞歸復(fù)制目錄,配置復(fù)制選項(覆蓋已存在文件)
Files.walkFileTree(sourcePath, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
// 創(chuàng)建目標目錄(遞歸)
Path targetDir = targetPath.resolve(sourcePath.relativize(dir));
if (!Files.exists(targetDir)) {
Files.createDirectories(targetDir);
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
// 復(fù)制文件(覆蓋已存在)
Path targetFile = targetPath.resolve(sourcePath.relativize(file));
Files.copy(file, targetFile, StandardCopyOption.REPLACE_EXISTING);
System.out.println("復(fù)制文件:" + file + " → " + targetFile);
return FileVisitResult.CONTINUE;
}
});
}
public static void main(String[] args) {
String sourceDir = "D:/test/source";
String targetDir = "D:/test/target";
try {
copyFolder(sourceDir, targetDir);
System.out.println("復(fù)制完成!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
總結(jié)
- 核心方案:
- 基礎(chǔ)版:使用
File+FileChannel實現(xiàn),兼容性好,適合理解底層邏輯; - 簡潔版:使用
Files.walkFileTree(Java 7+),代碼更簡潔,無需手動處理遞歸和文件復(fù)制;
- 基礎(chǔ)版:使用
- 關(guān)鍵要點:
- 先校驗源文件夾合法性,自動創(chuàng)建目標多級目錄;
- 區(qū)分文件/目錄,文件用通道復(fù)制(高效),目錄遞歸處理;
- 處理文件覆蓋/權(quán)限問題,保證復(fù)制健壯性;
- 適配場景:支持任意大小文件、多級目錄、跨系統(tǒng)路徑,滿足絕大多數(shù)文件夾復(fù)制需求。
以上就是Java中把一個文件夾下的所有文件復(fù)制到另一個文件夾的完整實現(xiàn)方案的詳細內(nèi)容,更多關(guān)于Java把一個文件夾所有文件復(fù)制到另一個文件夾的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Kotlin Coroutines執(zhí)行異步加載示例詳解
這篇文章主要給大家介紹了關(guān)于Kotlin Coroutines執(zhí)行異步加載的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。2018-01-01
Java實現(xiàn)一個達達租車系統(tǒng)的步驟詳解
這篇文章主要給大家介紹了利用Java實現(xiàn)一個達達租車系統(tǒng)的步驟,文中給出了詳細的實現(xiàn)思路和示例代碼,并在文末給出了完整的源碼供大家學習下載,需要的朋友可以參考借鑒,下面來一起看看吧。2017-04-04

