Java 提供多種文件讀取 API,針對不同文件類型(二進制、文本、大文件、隨機存取)選擇恰當的流,能顯著提升效能與程式碼可維護性。本文系統整理四大核心輸入流的使用場景、關鍵方法與完整範例。
| 流類別 | 讀取單位 | 適用場景 | 核心方法 |
|---|---|---|---|
| FileInputStream | 位元組 | 圖片、音訊、視訊等二進制文件 | read(), read(byte[]) |
| InputStreamReader | 字符 | 文本文件、需指定編碼 | read(), read(char[]) |
| BufferedReader | 行 | 格式化文本、日誌、CSV 逐行處理 | readLine() |
| RandomAccessFile | 位元組/字符 | 大文件隨機讀取、斷點續傳 | seek(), read(), readLine() |
package book.io;
import java.io.*;
public class ReadFromFile {
// 1. 位元組流:讀取二進制文件
public static void readFileByBytes(String fileName) {
File file = new File(fileName);
try (FileInputStream in = new FileInputStream(file)) {
System.out.println("--- 單位元組讀取 ---");
int b;
while ((b = in.read()) != -1) System.out.write(b);
System.out.println("\n--- 批次讀取 (100 bytes) ---");
byte[] buf = new byte[100];
int len;
try (FileInputStream in2 = new FileInputStream(fileName)) {
while ((len = in2.read(buf)) != -1) System.out.write(buf, 0, len);
}
} catch (IOException e) { e.printStackTrace(); }
}
// 2. 字符流:讀取文本文件
public static void readFileByChars(String fileName) {
File file = new File(fileName);
try (InputStreamReader reader = new InputStreamReader(new FileInputStream(file), "UTF-8")) {
System.out.println("--- 單字符讀取 ---");
int ch;
while ((ch = reader.read()) != -1) {
if (ch != '\r') System.out.print((char) ch);
}
System.out.println("\n--- 批次字符讀取 (30 chars) ---");
char[] cbuf = new char[30];
int clen;
try (InputStreamReader reader2 = new InputStreamReader(new FileInputStream(fileName), "UTF-8")) {
while ((clen = reader2.read(cbuf)) != -1) {
for (int i = 0; i < clen; i++) if (cbuf[i] != '\r') System.out.print(cbuf[i]);
}
}
} catch (IOException e) { e.printStackTrace(); }
}
// 3. 緩衝行讀取:最高效處理文本行
public static void readFileByLines(String fileName) {
try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
System.out.println("--- 逐行讀取 ---");
String line;
int no = 1;
while ((line = br.readLine()) != null) {
System.out.println("line " + no++ + ": " + line);
}
} catch (IOException e) { e.printStackTrace(); }
}
// 4. 隨機存取:跳轉至指定位置讀取
public static void readFileByRandomAccess(String fileName) {
try (RandomAccessFile raf = new RandomAccessFile(fileName, "r")) {
System.out.println("--- 隨機讀取 (從第 4 位元組開始) ---");
long len = raf.length();
int start = (len > 4) ? 4 : 0;
raf.seek(start);
byte[] buf = new byte[10];
int r;
while ((r = raf.read(buf)) != -1) System.out.write(buf, 0, r);
} catch (IOException e) { e.printStackTrace(); }
}
public static void main(String[] args) {
String path = "C:/Users/Admin/Desktop/CAI/20160718/newTemp.txt";
readFileByBytes(path);
readFileByChars(path);
readFileByLines(path);
readFileByRandomAccess(path);
}
}
InputStreamReader 建構子務必指定 charset(如 UTF-8),預設編碼因平台而異。BufferedReader 內部 8KB 緩衝,逐行讀取效能遠優於單字符讀取。"r" 唯讀、"rw" 讀寫,seek() 定位後可配合 read() 或 readLine()。BufferedReader;需隨機讀取區塊用 RandomAccessFile 或 MappedByteBuffer(NIO 記憶體映射)。FileInputStream.read() 逐位元組讀取大文本,效能極差。RandomAccessFile 在「r」模式下嘗試寫入拋出異常。掌握四大輸入流的特性與適用場景,並養成 try-with-resources 與明確編碼的習慣,是 Java I/O 開發的基本功。