CodeGym /課程 /JAVA 25 SELF /類別 File、Path、Files:取得檔案資訊

類別 File、Path、Files:取得檔案資訊

JAVA 25 SELF
等級 39 , 課堂 1
開放

1. 複習:File vs Path vs Files

經典的 File

唉…… 在 Java 專案裡遺留(legacy)程式碼比比皆是。因此讓我們再回顧一下這位資深角色——Java 的 File 類別。它自第一版就存在,可用來操作檔案與資料夾:判斷檔案是否存在、名稱、大小、修改日期,建立與刪除檔案和資料夾。如你所知,它也有不少缺點:部分方法不直覺、不是所有操作都跨平台,而且有些方法遇到錯誤不丟出例外,而是回傳 false(對除錯並不友善)。

import java.io.File;

File file = new File("example.txt");
System.out.println("檔案是否存在? " + file.exists());
System.out.println("是檔案嗎? " + file.isFile());
System.out.println("是資料夾嗎? " + file.isDirectory());

Path 與 Files:現代觀點(Java 7+)

自 Java 7 起加入套件 java.nio.file,提供更強大與彈性的工具。兩位關鍵角色:

  • Path — 介面,用來描述檔案或資料夾的路徑。可說是「有智慧的字串」:能解析、組合、分析、比較路徑。
  • Files — 提供大量靜態方法的工具類別:建立、刪除、複製、讀取、寫入與取得資訊。
import java.nio.file.Path;
import java.nio.file.Paths;

Path path = Paths.get("example.txt");
System.out.println("路徑: " + path);

小知識:類別 Path 不只是字串!它了解目錄分隔符,能處理相對與絕對路徑,並可在 Windows 與 Linux 上一致運作。

File 與 Path/Files 的比較表

比較項 File(舊 API) Path + Files(新 API)
語法 OOP 風格 組合使用 Path + Files 的靜態方法
跨平台性 部分支援 極佳,會考量作業系統
例外處理 不一定 幾乎都會
新功能 沒有 有(屬性、權限、連結等)
是否建議 通常不建議 建議

2. 取得檔案/目錄的資訊

來看看如何取得檔案或資料夾的關鍵資訊:是否存在、類型(檔案或目錄)、大小、名稱、路徑與父目錄。

檢查是否存在

使用 File

File file = new File("example.txt");
if (file.exists()) {
    System.out.println("檔案存在!");
} else {
    System.out.println("找不到檔案。");
}

使用 PathFiles

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

Path path = Paths.get("example.txt");
if (Files.exists(path)) {
    System.out.println("檔案存在!");
} else {
    System.out.println("找不到檔案。");
}

建議:新專案請一律使用 PathFiles。它更安全、好用且跨平台。

判斷類型:檔案還是目錄

File

if (file.isFile()) {
    System.out.println("這是檔案。");
} else if (file.isDirectory()) {
    System.out.println("這是資料夾。");
}

Path + Files

if (Files.isRegularFile(path)) {
    System.out.println("這是檔案。");
} else if (Files.isDirectory(path)) {
    System.out.println("這是資料夾。");
}

取得檔案大小

File

long size = file.length();
System.out.println("檔案大小: " + size + " 位元組");

Path + Files

try {
    long size = Files.size(path);
    System.out.println("檔案大小: " + size + " 位元組");
} catch (IOException e) {
    System.out.println("取得檔案大小時發生錯誤: " + e.getMessage());
}

注意:對於資料夾,方法 length() 總是回傳 0,而 Files.size(path) 會丟出 IOException。資料夾大小是其中所有檔案大小的總和(詳見後續課程)。

取得絕對與相對路徑

File

System.out.println("相對路徑: " + file.getPath());
System.out.println("絕對路徑: " + file.getAbsolutePath());

Path

System.out.println("相對路徑: " + path);
System.out.println("絕對路徑: " + path.toAbsolutePath());

取得檔名與父目錄

File

System.out.println("檔名: " + file.getName());
System.out.println("父資料夾: " + file.getParent());

Path

System.out.println("檔名: " + path.getFileName());
System.out.println("父資料夾: " + path.getParent());

小技巧:Path 不僅能處理檔案,也能處理資料夾、相對與絕對路徑,並且容易將路徑拆解成各部分。

3. 取得檔案屬性

有時我們想知道的不只是檔名與大小,還包括:建立時間、最後修改時間、存取權限。

建立時間與最後修改時間

File(功能受限)

long lastModified = file.lastModified();
System.out.println("最後修改時間: " + new java.util.Date(lastModified));

缺點:使用 File 無法取得檔案的建立時間!

Path + Files

import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;

try {
    BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
    FileTime creationTime = attrs.creationTime();
    FileTime lastModifiedTime = attrs.lastModifiedTime();

    System.out.println("建立時間: " + creationTime);
    System.out.println("最後修改時間: " + lastModifiedTime);
} catch (IOException e) {
    System.out.println("取得屬性時發生錯誤: " + e.getMessage());
}

檢查存取權限

File

System.out.println("可讀? " + file.canRead());
System.out.println("可寫? " + file.canWrite());
System.out.println("可執行? " + file.canExecute());

Path + Files

System.out.println("可讀? " + Files.isReadable(path));
System.out.println("可寫? " + Files.isWritable(path));
System.out.println("可執行? " + Files.isExecutable(path));

小知識:在 Windows 上存取權限較為受限,而在 Unix 系統中可以取得並變更更多權限(例如透過 POSIX 屬性)。

4. 取得檔案資訊時的常見錯誤

錯誤 №1:該用 Path 卻使用了 File
許多新手仍沿用 File,因為覺得較簡單,或是「網路上都是這麼寫」。但使用 PathFiles 能做同樣的事,卻更可靠、也更現代。

錯誤 №2:只用 File 來判斷類型。
若只用 file.isFile()file.isDirectory(),可能會忽略「特殊」檔案(符號連結、裝置檔等)。在現代 API 中有 Files.isRegularFile(path)Files.isDirectory(path) 與其他檢查可用。

錯誤 №3:忽略例外。
方法 Files.size(path)Files.readAttributes(...) 會丟出 IOException。若不處理例外,程式在第一個存取錯誤或檔案於執行期間消失時就會崩潰。

錯誤 №4:以為可以直接取得資料夾大小。
對資料夾呼叫 Files.size(path) 會拋出例外。要取得資料夾大小,必須遞迴加總其中所有檔案的大小。

錯誤 №5:未充分檢查存取權限。
即便檔案存在,你也可能沒有讀寫權限。執行操作前務必先檢查權限:Files.isReadable(path)Files.isWritable(path)Files.isExecutable(path)

留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION