檔案與磁碟操作是 Java 開發的基礎核心技能。本文系統整理從目錄列舉、檔案對話框、中文檔案複製陷阱、Unicode 處理、資料存取、效能原則到磁碟空間查詢與格式化等實戰技術,助你避開常見坑點,寫出健壯高效的 IO 程式碼。
File myDir = new File("C:/Windows/.");
String[] fileNames = myDir.list();
list() 回傳字串陣列,若需 File 物件陣列可用 listFiles()。記得處理 null 回傳值(目錄不存在或非目錄)。
| 技術 | 核心類別 | 特點 |
|---|---|---|
| AWT | FileDialog + FilenameFilter | 原生外觀,功能簡單 |
| Swing | JFileChooser + FileFilter | 跨平台一致、功能豐富、可自訂預覽 |
建議:優先使用 Swing 方案,支援多檔選擇、檔案過濾器、自訂配件等進階功能。
// FileReader → FileOutputStream:高位元組被丟棄
int c;
while ((c = myFileReader.read()) != -1)
myFileOutputStream.write(c); // write(int) 僅寫入低 8 bits
// 方案一:Reader/Writer 成對使用(字元流)
while ((c = myFileReader.read()) != -1)
myFileWriter.write(c); // write(int) 寫入完整 char (16 bits)
// 方案二:InputStream/OutputStream 成對使用(位元組流)
while ((c = myFileInputStream.read()) != -1)
myFileOutputStream.write(c);
核心原因:FileReader.read() 回傳 0~65535 (char),FileWriter.write(int) 接受 char;但 FileOutputStream.write(int) 只寫入低 8 bits,導致雙位元組字元截斷。
鐵律:永遠「字元流配字元流、位元組流配位元組流」,切勿混用。
// 寫入 UTF-8
myJTextArea.append("\u00E1"); // á
myJTextArea.append("\u00E2"); // â
myFileOutputStream.write(myJTextArea.getText().getBytes("UTF-8"));
// 讀取並還原
byte[] b = new byte[(int)myFile.length()];
new FileInputStream(myFile).read(b);
myJTextArea.append(new String(b, "UTF-8"));
統一使用 UTF-8 編碼可確保跨平台字元正確顯示與儲存。
| 類別組合 | 適用場景 | 注意事項 |
|---|---|---|
DataInputStream/DataOutputStream | 科學計算、基本型別序列化 | 無額外開銷,跨語言需約定位元組序 |
ObjectInputStream/ObjectOutputStream | 物件圖完整序列化 | 含類元資料,檔案較大、頻寬需求高 |
DataInputStream in = new DataInputStream(new FileInputStream(inFile));
DataOutputStream out = new DataOutputStream(new FileOutputStream(outFile));
BufferedInputStream、byte[] 批次讀寫)。read()/write()。Java 標準庫 無純 Java 方案。常見替代方案:
dir、Linux: df -k),但跨平台、多語系環境下極不穩定。Java 6+ 可用
File.getFreeSpace()、getUsableSpace()、getTotalSpace()直接取得,無需外部相依。
純 Java 無解,需呼叫系統工具。Windows 範例:
// FormatDrive.bat
rundll32.exe shell32.dll, SHFormatDrive
// Java 呼叫
public void formatDrive() {
try {
Process p = Runtime.getRuntime().exec("FormatDrive.bat");
p.waitFor();
} catch (Exception e) { e.printStackTrace(); }
}
警告:執行前請三思,資料無價!
// Java 1.2+ 標準做法
File[] roots = File.listRoots();
for (File root : roots) System.out.println(root);
Windows 回傳磁碟機代號(C:、D:...),Linux/Unix 僅回傳根目錄 /。
檔案操作看似基礎,細節決定成敗。記住:分清位元組/字元流、善用緩衝、優先標準 API、跨平台謹慎用 JNI/系統指令。現代專案建議直接使用 java.nio.file (NIO.2) 獲得更豐富、更安全、更高效的檔案系統操作體驗。