File 類核心定位
java.io.File 代表文件/目錄路徑名的抽象表示,不包含文件內容。用於:創建、刪除、重命名、屬性獲取、目錄遍歷。讀寫內容需用流 (FileInputStream/FileReader 等)。
路徑相關方法
File file = new File("d:/data/test.txt");
file.getName(); // test.txt (文件名)
file.getPath(); // d:/data/test.txt (構造路徑)
file.getAbsolutePath(); // D:\data\test.txt (絕對路徑)
file.getParent(); // d:/data (父目錄)
file.getParentFile(); // File 對象
file.toPath(); // 轉為 Path (Java 7+ NIO.2)
file.toURI(); // file:///D:/data/test.txt
屬性檢測方法
| 方法 | 返回值 | 說明 |
| exists() | boolean | 文件/目錄是否存在 |
| isFile() | boolean | 是否為文件 |
| isDirectory() | boolean | 是否為目錄 |
| isAbsolute() | boolean | 是否為絕對路徑 |
| canRead() | boolean | 是否可讀 |
| canWrite() | boolean | 是否可寫 |
| isHidden() | boolean | 是否隱藏 |
| length() | long | 文件大小(字節),目錄返回 0 |
| lastModified() | long | 最後修改時間(毫秒時間戳) |
創建與刪除
// 創建文件 (不覆蓋已存在)
boolean created = file.createNewFile(); // 父目錄必須存在
// 創建目錄
file.mkdir(); // 單級目錄,父目錄必須存在
file.mkdirs(); // 多級目錄,自動創建父目錄
// 刪除
boolean deleted = file.delete(); // 刪除文件/空目錄,非空目錄失敗
// 刪除非空目錄需遞歸
public void deleteDir(File dir) {
File[] files = dir.listFiles();
if (files != null) {
for (File f : files) {
if (f.isDirectory()) deleteDir(f);
else f.delete();
}
}
dir.delete();
}
目錄遍歷與文件查找
1. 列出所有文件/子目錄
File dir = new File("D:/data");
File[] files = dir.listFiles(); // 返回 File[],null 表示非目錄或 IO 錯誤
if (files != null) {
for (File f : files) {
System.out.println(f.getName() + (f.isDirectory() ? "/" : ""));
}
}
2. 遞歸遍歷整棵目錄樹
public void walkTree(File root, String indent) {
System.out.println(indent + root.getName() + (root.isDirectory() ? "/" : ""));
if (root.isDirectory()) {
File[] children = root.listFiles();
if (children != null) {
for (File child : children) {
walkTree(child, indent + " ");
}
}
}
}
// 調用: walkTree(new File("D:/data"), "");
3. 文件過濾器
// FileFilter: 過濾 File 對象
File[] txtFiles = dir.listFiles(new FileFilter() {
@Override public boolean accept(File pathname) {
return pathname.getName().endsWith(".txt");
}
});
// FilenameFilter: 過濾文件名 (目錄+名稱)
File[] noAFiles = dir.listFiles(new FilenameFilter() {
@Override public boolean accept(File dir, String name) {
return !name.endsWith("a");
}
});
// Java 8 Lambda 簡寫
File[] jpgFiles = dir.listFiles(f -> f.getName().endsWith(".jpg"));
File[] bigFiles = dir.listFiles(f -> f.length() > 1024 * 1024); // > 1MB
4. Java 7+ NIO.2 Files.walk (推薦大目錄)
try (Stream<Path> stream = Files.walk(Paths.get("D:/data"))) {
stream.filter(Files::isRegularFile)
.filter(p -> p.toString().endsWith(".log"))
.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
臨時文件創建
// 默認臨時目錄創建
File tempFile = File.createTempFile("prefix", ".tmp");
// 指定目錄
File tempFile = File.createTempFile("prefix", ".tmp", new File("/custom/temp"));
// 退出時自動刪除
tempFile.deleteOnExit();
// 獲取系統臨時目錄
String tmpDir = System.getProperty("java.io.tmpdir");
文件重命名與移動
File src = new File("d:/a.txt");
File dest = new File("d:/b.txt");
// renameTo: 可跨目錄移動,目標存在則失敗 (平台相關)
boolean renamed = src.renameTo(dest);
// Java 7+ Files.move (功能更強)
Files.move(src.toPath(), dest.toPath(),
StandardCopyOption.REPLACE_EXISTING, // 覆蓋
StandardCopyOption.ATOMIC_MOVE); // 原子移動 (同文件系統)
實戰工具類封裝
public class FileUtils {
/** 獲取文件擴展名 */
public static String getExtension(File file) {
String name = file.getName();
int idx = name.lastIndexOf('.');
return idx > 0 ? name.substring(idx + 1) : "";
}
/** 獲取不帶擴展名的文件名 */
public static String getBaseName(File file) {
String name = file.getName();
int idx = name.lastIndexOf('.');
return idx > 0 ? name.substring(0, idx) : name;
}
/** 格式化文件大小 */
public static String formatSize(long bytes) {
if (bytes < 1024) return bytes + " B";
int exp = (int) (Math.log(bytes) / Math.log(1024));
String unit = "KMGTPE".charAt(exp - 1) + "B";
return String.format("%.2f %s", bytes / Math.pow(1024, exp), unit);
}
/** 讀取文件所有行 (Java 8+) */
public static List<String> readLines(File file) throws IOException {
return Files.readAllLines(file.toPath(), StandardCharsets.UTF_8);
}
/** 寫入文件 (Java 7+) */
public static void writeLines(File file, Collection<String> lines) throws IOException {
Files.write(file.toPath(), lines, StandardCharsets.UTF_8,
StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
}
/** 複製文件 (Java 7+) */
public static void copyFile(File src, File dest) throws IOException {
Files.copy(src.toPath(), dest.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
}
File vs Path (NIO.2) 對比
| 特性 | java.io.File | java.nio.file.Path |
| API 風格 | 面向對象 | 函數式/流式 |
| 異常處理 | 返回 boolean/false | 拋出 IOException |
| 符號鏈接 | 支持差 | 完整支持 |
| 屬性讀取 | 基礎 | 豐富 (BasicFileAttributes 等) |
| 目錄遍歷 | listFiles (載入全部) | Files.walk (流式、懶加載) |
| 推薦場景 | 簡單操作、舊代碼兼容 | 新項目、複雜操作、大目錄 |
避坑指南
| 坑點 | 說明 | 正確做法 |
| listFiles 返回 null | 非目錄、無權限、IO 錯誤 | 使用前判空 |
| delete 非空目錄失敗 | 只能刪空目錄 | 遞歸刪除子文件後再刪目錄 |
| renameTo 跨盤符失敗 | Windows 跨磁盤不可重命名 | 用 Files.move + REPLACE_EXISTING |
| 路徑分隔符硬編碼 | Windows \ vs Linux / | 用 File.separator 或 Paths.get() |
| 相對路徑依賴工作目錄 | user.dir 可能變 | 優先用絕對路徑或相對項目根目錄 |
總結
File 類是文件系統操作的入口,核心掌握:路徑獲取、屬性檢測、創建刪除、目錄遍歷 (listFiles/Files.walk)、過濾器、臨時文件、重命名移動。新項目優先使用 java.nio.file.Files/Path 獲得更豐富功能、更好異常處理、流式處理大目錄優勢。工具類封裝常用操作提升開發效率。