使用 Maven 開發專案時,相信許多開發者都深有同感:「每次開發完成,都必須執行 Maven 打包部署」。若專案引入了自訂 Maven 插件(包含自定義邏輯),每次修改都得重新 package,開發效率極其低下。嘗試使用同步工具卻問題頻出,索性自己動手寫一個檔案同步程式,實現原始碼修改後自動同步到 JBoss 虛擬目錄,實現熱部署效果。
同步邏輯主要包含三個步驟:
.svn 等版本控制目錄,支援自訂 FileFilter。package com.ycl.filter.FileCleaner;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.io.IOUtils;
public class FileSyn {
static Map<String, String> map = new HashMap<String, String>();
/**
* 同步單一來源目錄到目標目錄(預設排除 .svn)
*/
public static void synFile(String target, String source) {
File sourcePath = new File(source);
File targetPath = new File(target);
index(sourcePath);
synPath(sourcePath, targetPath, new FileFilter() {
@Override
public boolean accept(File file) {
return !file.getAbsolutePath().contains(".svn");
}
});
}
/**
* 支援自訂過濾器的同步入口
*/
public static void synFile(String target, String source, FileFilter fileFilter) {
File sourcePath = new File(source);
File targetPath = new File(target);
index(sourcePath);
synPath(sourcePath, targetPath, fileFilter);
}
/**
* 遞歸同步兩目錄下的檔案
*/
public static void synPath(File sourcePath, File targetPath, FileFilter fileFilter) {
if (sourcePath.isDirectory()) {
File[] files = sourcePath.listFiles(fileFilter);
for (File sourceFile : files) {
try {
if (sourceFile.isDirectory()) {
File targetFile = new File(targetPath, sourceFile.getName());
if (!targetFile.exists()) {
targetFile.mkdirs(); // 修正:目錄用 mkdirs()
}
synPath(sourceFile, targetFile, fileFilter);
} else if (sourceFile.isFile()) {
File targetFile = new File(targetPath, sourceFile.getName());
if (!targetFile.exists()) {
targetFile.createNewFile();
}
boolean flag = synFile(sourceFile, targetFile);
if (flag) {
System.out.println("同步檔案:[" + sourceFile.getAbsolutePath() + "," + targetFile.getAbsolutePath() + "]成功!");
}
}
} catch (IOException e) {
System.out.println("來源檔案:" + sourceFile.getAbsolutePath());
e.printStackTrace();
}
}
}
}
/**
* 檔案級同步:僅在來源較新時覆蓋目標
*/
public static boolean synFile(File sourceFile, File targetFile) {
boolean flag = false;
Reader reader = null;
Writer writer = null;
try {
// 僅示範邏輯,實際建議用 Files.copy 或 NIO 提升效能
if (sourceFile.lastModified() > targetFile.lastModified()) {
reader = new FileReader(sourceFile);
writer = new FileWriter(targetFile);
IOUtils.copy(reader, writer);
flag = true;
}
} catch (IOException e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(reader);
IOUtils.closeQuietly(writer);
}
return flag;
}
/** 索引來源目錄檔案(可擴充為記錄修改時間供增量判斷) */
private static void index(File path) {
// 實作略
}
}
Files.walkFileTree + Files.copy(..., StandardCopyOption.REPLACE_EXISTING) 更簡潔高效。WatchService 實現真正的「存檔即同步」,無需手動觸發。target/、.class 等非必要檔案,減少同步量。自製同步工具雖然初期投入較小,但能徹底解決「改代碼 → 打包 → 部署 → 驗證」的漫長循環。配合現代 IDE 與 NIO API,可構建輕量級熱部署流程,大幅提升開發體驗。若專案規模較大,建議評估 JRebel、Spring Boot DevTools 等成熟方案。