java.io.File 是 Java 檔案系統操作的入口類,**僅代表路徑抽象,不保證檔案實體存在**。本文深度解析 6 個建構子、核心 API、實戰陷阱與最佳實踐。
// 1. 路徑字串(相對/絕對)
public File(String pathname) { ... }
new File("data/config.properties");
new File("/home/user/data/config.properties");
new File("C:\\Users\\data\\config.properties");
// 2. URI
public File(URI uri) { ... }
new File(new URI("file:///home/user/data/config.properties"));
// 3. 父路徑字串 + 子路徑字串
public File(String parent, String child) { ... }
new File("/home/user/data", "config.properties");
// 4. 父 File 物件 + 子路徑字串
public File(File parent, String child) { ... }
File parentDir = new File("/home/user/data");
new File(parentDir, "config.properties");
File(String pathname, int prefixLength):已正規化路徑File(String child, File parent):子路徑在前,父 File 在後// 跨平台安全
File file = new File(System.getProperty("user.home"), "data/config.properties");
// 或 Java 7+ Paths
Path path = Paths.get(System.getProperty("user.home"), "data", "config.properties");
File file = path.toFile();
| 方法 | 回傳 | 行為 | 常見坑 |
|---|---|---|---|
| mkdir() | boolean | 創建單層目錄,父目錄必須存在 | 父目錄不存在回傳 false,不拋異常 |
| mkdirs() | boolean | 創建多層目錄(含父目錄) | 部分創建成功後失敗,不回滾 |
| createNewFile() | boolean | 創建新檔案(原子操作) | 檔案已存在回傳 false;目錄不存在拋 IOException |
| delete() | boolean | 刪除檔案/空目錄 | 非空目錄回傳 false;不進入回收桶 |
| deleteOnExit() | void | JVM 正常關閉時刪除 | 僅正常關閉生效;臨時檔案常用 |
public static File safeCreateFile(String dirPath, String fileName) throws IOException {
File dir = new File(dirPath);
if (!dir.exists()) {
if (!dir.mkdirs()) {
throw new IOException("無法創建目錄: " + dirPath);
}
} else if (!dir.isDirectory()) {
throw new IOException("路徑存在但非目錄: " + dirPath);
}
File file = new File(dir, fileName);
if (!file.createNewFile()) {
// 檔案已存在,根據業務決定覆蓋或拋錯
}
return file;
}
File f = new File("test.txt");
f.exists(); // 檔案/目錄是否存在
f.isFile(); // 是否為檔案
f.isDirectory(); // 是否為目錄
f.isHidden(); // 是否隱藏(平台相關)
f.isAbsolute(); // 是否絕對路徑
f.canRead(); // 可讀
f.canWrite(); // 可寫
f.canExecute(); // 可執行
f.getName(); // 檔名(不含路徑)
f.getPath(); // 建構子傳入的路徑
f.getAbsolutePath(); // 絕對路徑字串
f.getCanonicalPath(); // 規範路徑(解析 . .. 符號連結)
f.getParent(); // 父目錄路徑字串
f.getParentFile(); // 父目錄 File 物件
f.length(); // 檔案大小(位元組),目錄回傳 0
f.lastModified(); // 最後修改時間(毫秒時間戳)
new Date(f.lastModified()); // 轉 Date
// 僅名稱(字串陣列)
String[] names = dir.list(); // 非目錄回傳 null,空目錄回傳長度 0 陣列
// 過濾器版本
String[] javaFiles = dir.list((d, name) -> name.endsWith(".java"));
// File 物件陣列(推薦)
File[] files = dir.listFiles(); // 同樣:非目錄 null,空目錄空陣列
File[] javaFiles = dir.listFiles(f -> f.isFile() && f.getName().endsWith(".java"));
// 遞迴遍歷(Java 7+ NIO.2 更推薦)
Files.walkFileTree(Paths.get("."), new SimpleFileVisitor<>() {
@Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
System.out.println(file);
return FileVisitResult.CONTINUE;
}
});
// 重命名/移動(同檔案系統原子操作)
boolean success = file.renameTo(new File("/new/path/name.txt"));
// 路徑轉 URI / URL
URI uri = file.toURI(); // file:///path
URL url = file.toURI().toURL(); // file:/path (舊 API)
// 相對路徑轉絕對
File abs = file.getAbsoluteFile();
Path path = Paths.get("/home/user/data.txt");
// 原子操作、更豐富屬性、更好異常處理
Files.createDirectories(path.getParent());
Files.write(path, "content".getBytes(StandardCharsets.UTF_8));
String content = Files.readString(path, StandardCharsets.UTF_8);
Files.copy(src, dest, StandardCopyOption.REPLACE_EXISTING);
Files.move(src, dest, StandardCopyOption.ATOMIC_MOVE);
Files.walk(path).filter(Files::isRegularFile).forEach(System.out::println);
// 屬性讀取
BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
attrs.size(); attrs.creationTime(); attrs.lastModifiedTime(); attrs.isDirectory();
File 類是 Java 檔案操作的基石,掌握其建構子語義、目錄操作原子性、屬性判斷邊界條件,是寫出健壯檔案處理代碼的前提。**新專案優先使用 NIO.2 `Path`/`Files` API**,功能更強、異常更精確、支援串流與非同步操作。