在 Java 早期版本中,標準 API 長期缺乏直接獲取磁碟剩餘空間的能力(直到 Java 1.6 才引入 File.getFreeSpace() 等方法)。開發者不得不另闢蹊徑,本文將深度解析三種經典跨平台獲取磁碟空間的方案,剖析其原理、優缺點與適用場景,助您根據專案需求做出最佳技術選型。
最直觀但也最脆弱的方式:執行作業系統原生指令(Windows dir、Linux/Unix df),擷取標準輸出並解析文字。
public static long getFreeDiskSpaceWindows(String dirName) {
try {
// 區分舊版 Windows (command.com) 與 NT 核心 (cmd.exe)
String os = System.getProperty("os.name");
String cmd = (os.contains("Windows 9") || os.contains("Windows ME"))
? "command.com /c dir " + dirName
: "cmd.exe /c dir " + dirName;
Process process = Runtime.getRuntime().exec(cmd);
BufferedReader in = new BufferedReader(
new InputStreamReader(process.getInputStream()));
String line, lastLine = "";
while ((line = in.readLine()) != null) lastLine = line; // 取最後一行
// 解析 "X bytes free" 等格式,移除逗號、句點後轉長整數
// ... 字串處理邏輯較繁瑣,此處省略 ...
return parsedBytes;
} catch (Exception e) {
return -1; // 失敗返回 -1
}
}
| 優點 | 缺點 |
|---|---|
| 無需第三方庫,純 JDK 實現 | 極度依賴作業系統與地區設定(輸出語言、日期格式、單位皆可能不同) |
| 概念簡單,易於理解 | 啟動進程開銷大,效能低,不適合高頻呼叫 |
| 需分別維護 Windows/Linux/macOS 多套解析邏輯 | |
| 安全風險:命令注入隱患(若路徑含特殊字元) |
結論: 僅適合快速原型、工具腳本或極舊版 Java 環境(< 1.6)的維護專案。生產環境強烈不推薦。
在 Java 1.6 之前,JConfig 是知名的開源解決方案,封裝了各平台原生 API。
// JConfig 風格範例 (需引入 jconfig.jar)
import jconfig.*;
FileRegistry registry = FileRegistry.getRegistry();
DiskVolume[] volumes = registry.getVolumes();
for (DiskVolume vol : volumes) {
long free = vol.getFreeSpace(); // 剩餘位元組
long total = vol.getMaxCapacity(); // 總容量
System.out.println(vol.getName() + ": " + free + "/" + total);
}
終極核武器:編寫 C/C++ 代碼調用 OS API (GetDiskFreeSpaceEx on Windows, statvfs on POSIX),編譯為動態庫,Java 端透過 native 方法調用。
// Java 端聲明
public class DiskSpaceJNI {
static { System.loadLibrary("diskspace"); } // 載入 dll/so
public native long getFreeSpace(String path);
public native long getTotalSpace(String path);
}
// C++ 端實現 (Windows 範例) #include#include JNIEXPORT jlong JNICALL Java_DiskSpaceJNI_getFreeSpace(JNIEnv *env, jobject obj, jstring path) { const char *p = env->GetStringUTFChars(path, 0); ULARGE_INTEGER freeBytes; GetDiskFreeSpaceExA(p, &freeBytes, NULL, NULL); env->ReleaseStringUTFChars(path, p); return (jlong)freeBytes.QuadPart; }
**請直接使用標準庫,除非您被鎖定在 Java 1.5 或更舊版本。**
// Java 1.6+ (io 包)
File file = new File("C:\\"); // 或 "/"
long freeBytes = file.getFreeSpace();
long totalBytes = file.getTotalSpace();
long usableBytes = file.getUsableSpace(); // 當前用戶可用空間 (考慮配額)
// Java 7+ (nio.2 包,更強大)
Path path = Paths.get("/");
FileStore store = Files.getFileStore(path);
long free = store.getUsableSpace();
long total = store.getTotalSpace();
long unallocated = store.getUnallocatedSpace(); // 未分配空間
System.out.printf("類型: %s, 總計: %,d GB, 可用: %,d GB%n",
store.type(), total/1024/1024/1024, free/1024/1024/1024);
File.getFreeSpace() 或 Files.getFileStore(),**全文結束**。技術演進的歷程告訴我們:標準化 API 的誕生,往往是為了埋葬那些巧妙但脆弱的變通方案。 除非有極其特殊的硬性限制,請擁抱 java.nio.file 帶來的型別安全、跨平台一致性與豐富資訊。