專案常需動態建立資料夾、檔案或臨時檔。java.io.File 雖基礎,但細節多(跨平台路徑、父目錄不存在、原子建立、異常處理)。本文提供一個可直接落地的 CreateFileUtil,涵蓋三大核心功能,並修正原碼潛在 Bug(如 mkdirs() 回傳值誤判)。
createFile(String destFileName)mkdirs())createNewFile() 原子建立,避免競態createDir(String destDirName)File.separatortrue)mkdirs() 成功卻印「失敗」的邏輯錯誤createTempFile(prefix, suffix, dirName)java.io.tmpdirpackage com.xhkj.util;
import java.io.File;
import java.io.IOException;
public class CreateFileUtil {
/**
* 建立單一檔案
* @param destFileName 完整檔案路徑(含檔名)
* @return 成功 true,失敗 false
*/
public static boolean createFile(String destFileName) {
File file = new File(destFileName);
if (file.exists()) {
System.err.println("建立檔案失敗:" + destFileName + " 已存在");
return false;
}
if (destFileName.endsWith(File.separator)) {
System.err.println("建立檔案失敗:目標路徑為目錄而非檔案");
return false;
}
// 父目錄不存在則建立
File parent = file.getParentFile();
if (parent != null && !parent.exists()) {
System.out.println("父目錄不存在,自動建立:" + parent);
if (!parent.mkdirs()) {
System.err.println("建立父目錄失敗:" + parent);
return false;
}
}
try {
boolean created = file.createNewFile();
if (created) {
System.out.println("建立檔案成功:" + destFileName);
} else {
System.err.println("建立檔案失敗:" + destFileName);
}
return created;
} catch (IOException e) {
System.err.println("建立檔案異常:" + destFileName);
e.printStackTrace();
return false;
}
}
/**
* 建立目錄
* @param destDirName 目錄路徑
* @return 成功 true,失敗 false
*/
public static boolean createDir(String destDirName) {
File dir = new File(destDirName);
if (dir.exists()) {
System.err.println("建立目錄失敗:" + destDirName + " 已存在");
return false;
}
// 統一補齊分隔符,利於後續拼接
if (!destDirName.endsWith(File.separator)) {
destDirName += File.separator;
}
boolean created = dir.mkdirs();
if (created) {
System.out.println("建立目錄成功:" + destDirName);
} else {
System.err.println("建立目錄失敗:" + destDirName);
}
return created;
}
/**
* 建立臨時檔案
* @param prefix 前綴(至少 3 字元)
* @param suffix 後綴(含 .,如 ".tmp")
* @param dirName 目錄路徑,null 表使用系統預設臨時目錄
* @return 臨時檔案 canonical path,失敗回傳 null
*/
public static String createTempFile(String prefix, String suffix, String dirName) {
try {
File dir = (dirName == null) ? null : new File(dirName);
if (dir != null && !dir.exists()) {
if (!createDir(dirName)) {
System.err.println("建立臨時檔案失敗:無法建立目錄 " + dirName);
return null;
}
}
File tempFile = (dir == null) ?
File.createTempFile(prefix, suffix) :
File.createTempFile(prefix, suffix, dir);
return tempFile.getCanonicalPath();
} catch (IOException e) {
System.err.println("建立臨時檔案異常:" + e.getMessage());
e.printStackTrace();
return null;
}
}
// 測試主程式
public static void main(String[] args) {
String baseDir = "c:" + File.separator + "test" + File.separator + "test0" + File.separator + "test1";
createDir(baseDir);
String filePath = baseDir + File.separator + "test2" + File.separator + "testFile.txt";
createFile(filePath);
String prefix = "temp", suffix = ".txt";
for (int i = 0; i < 10; i++) {
String tmp = createTempFile(prefix, suffix, baseDir);
System.out.println("建立臨時檔案:" + tmp);
}
}
}
File.separator,Windows/Linux 皆相容。createNewFile() 保證檔案不存在時才建立,避免 TOCTOU 競態。createTempFile 產生的檔案,若需手動控制可搭配 deleteOnExit()。IOException 並列印堆疊,生產環境建議改用 SLF4J 記錄。若專案已升級 Java 7,推薦改用 java.nio.file.Files:
Path path = Paths.get(destFileName);
Files.createDirectories(path.getParent()); // 自動建立父目錄
Files.createFile(path); // 原子建立,檔案存在拋 FileAlreadyExistsException
NIO.2 API 更簡潔、支援符號連結、屬性讀寫,且例外訊息更豐富。