Java 文件操作 API 經歷了三代演進,理解其設計哲學有助於選型:
| 世代 | 核心抽象 | 特點 | 適用場景 |
|---|---|---|---|
| JDK 1.0 | InputStream/OutputStream (位元組流) |
基礎、通用、處理二進制/文字皆可 | 二進制檔案、網路流、舊系統相容 |
| JDK 1.1 | Reader/Writer (字符流) |
專注文字處理、內建編碼轉換、緩衝支援 | 純文字檔案、配置檔、日誌、跨平台文字處理 |
| JDK 1.4 (NIO) | Channel/Buffer/Selector |
非阻塞、記憶體映射、零拷貝、高併發 | 大檔案、高效能伺服器、網路密集型應用 |
| JDK 7 (NIO.2) | Path/Files/FileSystem |
現代化 API、串流操作、完善檔案屬性/監控 | 新專案首選、複雜檔案系統操作 |
FileInputStream fis = new FileInputStream(args[0]);
DataInputStream dis = new DataInputStream(fis);
while (dis.available() != 0) {
System.out.println(dis.readLine());
}
dis.close();
缺點:DataInputStream.readLine() 已棄用,不支援字符集指定,available() 非可靠 EOF 判斷。
FileOutputStream fos = new FileOutputStream("myfile.txt");
PrintStream ps = new PrintStream(fos);
ps.println("This is written to a file");
ps.close();
FileReader fr = new FileReader("mydata.txt");
BufferedReader br = new BufferedReader(fr);
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
fr.close();
優勢:BufferedReader 提供高效緩衝讀取,FileReader 使用平台預設編碼 (可透過 InputStreamReader 指定編碼)。
FileWriter fw = new FileWriter("mydata.txt");
PrintWriter pw = new PrintWriter(fw);
pw.println("hi, this will be written into the file!");
pw.close();
fw.close();
print vs println:後者自動換行。
try (BufferedReader br = new BufferedReader(new FileReader("file.txt", StandardCharsets.UTF_8))) {
String line;
while ((line = br.readLine()) != null) {
// 處理
}
} // 自動關閉,即使拋出異常
舊版本需在 finally 中分別關閉,且須處理 close() 可能拋出的異常。
永不依賴平台預設編碼:
// 讀取
new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"))
// 寫入
new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"))
BufferedReader / BufferedInputStreamBufferedWriter / BufferedOutputStreamInputStream/OutputStream)Reader/Writer)// 讀取所有行 (小檔案)
List lines = Files.readAllLines(path, StandardCharsets.UTF_8);
// 串流處理大檔案
try (Stream stream = Files.lines(path, StandardCharsets.UTF_8)) {
stream.filter(s -> s.contains("ERROR")).forEach(System.out::println);
}
// 寫入
Files.write(path, lines, StandardCharsets.UTF_8, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
// 檔案資訊
FileTime mtime = Files.getLastModifiedTime(path);
long size = Files.size(path);
// 目錄遍歷
Files.walkFileTree(root, new SimpleFileVisitor() {
@Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
System.out.println(file + " " + attrs.size());
return FileVisitResult.CONTINUE;
}
});
Files/Path) 為首選FileChannel)BufferedReader/BufferedWriter)BufferedInputStream/BufferedOutputStream)DataInputStream.readLine()、無緩衝的單字符讀寫、平台預設編碼Java 文件 I/O 從基礎流演進至現代化 NIO.2,核心原則不變:緩衝提升效能、字符集顯式指定、資源確實釋放。新專案應優先採用 java.nio.file.Files API,享受更安全、簡潔、功能豐富的檔案操作體驗。