java.io.File 代表文件系統中的路徑抽象,不僅是文件,也可以是目錄。它不負責讀寫內容(那是流的事),只負責元數據操作:創建/刪除/重命名/屬性查詢/目錄遍歷。
// 1. 分隔符自適應
String path = "data" + File.separator + "uploads" + File.separator + "img.jpg";
// 2. 相對路徑轉絕對路徑
File file = new File("config.properties");
String absPath = file.getAbsolutePath(); // 當前工作目錄下
// 3. 規範路徑(解析 . 和 ..)
String canonical = file.getCanonicalPath(); // 拋出 IOException
// 4. URI/URL 互轉
URI uri = file.toURI();
URL url = file.toURL(); // 棄用,建議用 toURI().toURL()
// 創建單個文件(不存在時)
File f = new File("log/app.log");
if (f.createNewFile()) System.out.println("創建成功");
// 創建多級目錄
File dir = new File("data/2024/01/15");
dir.mkdirs(); // 遞歸創建,返回 boolean
// 刪除(文件或空目錄)
f.delete(); // 非空目錄刪除失敗
// 遞歸刪除非空目錄(Java 7+ 推薦 Files.walkFileTree)
public static void deleteRecursive(File file) throws IOException {
if (file.isDirectory()) {
Files.walkFileTree(file.toPath(), new SimpleFileVisitor<Path>() {
@Override public FileVisitResult visitFile(Path f, BasicFileAttributes a) throws IOException {
Files.delete(f); return FileVisitResult.CONTINUE;
}
@Override public FileVisitResult postVisitDirectory(Path d, IOException e) throws IOException {
Files.delete(d); return FileVisitResult.CONTINUE;
}
});
} else {
Files.deleteIfExists(file.toPath());
}
}
@PostMapping("/upload")
public Result upload(@RequestParam MultipartFile file, HttpServletRequest request) {
// 1. 校驗
if (file.isEmpty()) return Result.error("文件為空");
String original = file.getOriginalFilename();
String ext = original.substring(original.lastIndexOf(".")).toLowerCase();
if (!Arrays.asList(".jpg", ".png", ".pdf").contains(ext)) return Result.error("類型不允許");
// 2. 生成唯一文件名
String storedName = UUID.randomUUID() + ext;
// 3. 目標目錄
String baseDir = request.getServletContext().getRealPath("/uploads");
File dir = new File(baseDir);
if (!dir.exists()) dir.mkdirs();
// 4. 保存(大文件建議流式複製)
File dest = new File(dir, storedName);
try {
file.transferTo(dest); // 底層用 FileChannel,效率高
// 或手動流複製:Files.copy(file.getInputStream(), dest.toPath())
return Result.success(storedName);
} catch (IOException e) {
log.error("上傳失敗", e);
return Result.error("存儲異常");
}
}
// 1. 列出所有(含隱藏)
File[] files = dir.listFiles();
// 2. FilenameFilter 過濾擴展名
File[] imgs = dir.listFiles((d, name) -> name.endsWith(".jpg") || name.endsWith(".png"));
// 3. FileFilter 過濾目錄/文件
File[] subDirs = dir.listFiles(File::isDirectory);
// 4. Java 8+ Stream 流式處理
Arrays.stream(dir.listFiles())
.filter(f -> f.isFile() && f.getName().matches(".*\\.log$"))
.sorted(Comparator.comparingLong(File::lastModified).reversed())
.limit(10)
.forEach(f -> System.out.println(f.getName() + " " + f.length()));
// 5. 遞歸遍歷(Java 7+ NIO.2)
Files.walk(Paths.get("data"))
.filter(Files::isRegularFile)
.filter(p -> p.toString().endsWith(".java"))
.forEach(System.out::println);
| 方法 | 說明 | 示例 |
|---|---|---|
exists() | 是否存在 | 上傳前檢查 |
isFile() / isDirectory() | 類型判斷 | 遍歷時區分 |
length() | 文件大小(字節) | 限制上傳大小 |
lastModified() | 最後修改時間戳 | 緩存失效判斷 |
canRead() / canWrite() / canExecute() | 權限檢查 | 腳本執行前驗證 |
getName() | 文件名(含擴展名) | 顯示/存儲 |
getParent() | 父目錄路徑 | 構建相對路徑 |
java.nio.file.Files + Path 提供更豐富、異常更明確、支援符號鏈接、流式操作的 API,新項目優先使用:
Path p = Paths.get("data", "file.txt");
Files.createDirectories(p.getParent());
Files.writeString(p, "內容", StandardCharsets.UTF_8);
String content = Files.readString(p);
Files.deleteIfExists(p);