Java IO 涉及 40 多個類,初學者極易混淆。本文以「字節 vs 字符」「節點 vs 處理」「轉換橋樑」三條主線,梳理完整體系結構,並提供高頻實戰代碼模板(InputStream↔String、文件讀寫、緩衝行讀),可直接複製落地。
| 維度 | 輸入流 (讀) | 輸出流 (寫) |
|---|---|---|
| 字節流 (二進制,萬能) | InputStream (抽象基類)核心方法: read(), read(byte[]), close() |
OutputStream (抽象基類)核心方法: write(int), write(byte[]), flush(), close() |
| 字符流 (文本,便捷) | Reader (抽象基類)核心方法: read(), read(char[]), close() |
Writer (抽象基類)核心方法: write(int), write(char[]), flush(), close() |
選型原則:處理文本優先字符流(自動處理編碼);圖片/視頻/二進制文件必須字節流;不確定時用字節流保底。
InputStream (字節輸入) ├── FileInputStream (文件源) ├── ByteArrayInputStream (內存字節數組源) ├── FilterInputStream (裝飾者基類) │ ├── BufferedInputStream (緩衝,提升性能) │ ├── DataInputStream (基本類型讀取) │ └── ObjectInputStream (對象反序列化) ├── PipedInputStream (管道通信) └── SequenceInputStream (合併多輸入流) OutputStream (字節輸出) ... 對應結構 Reader (字符輸入) ├── InputStreamReader (字節→字符轉換橋樑,指定編碼) │ └── BufferedReader (緩衝行讀 readLine()) ├── FileReader (便捷文件字符讀,默認編碼) ├── CharArrayReader (字符數組源) ├── PipedReader (管道) └── StringReader (字符串源) Writer (字符輸出) ... 對應結構
核心類:
InputStreamReader:字節輸入流 → 字符輸入流(解碼,指定 charset)OutputStreamWriter:字節輸出流 → 字符輸出流(編碼,指定 charset)// 模板:BufferedReader 包裝 InputStreamReader,指定 UTF-8
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(new FileInputStream("data.txt"), StandardCharsets.UTF_8))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line); // 業務處理
}
}
public static String inputStreamToString(InputStream is, String charset) throws IOException {
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
return baos.toString(charset);
}
}
public static String inputStreamToStringBuffer(InputStream is, String charset) throws IOException {
StringBuffer sb = new StringBuffer();
try (InputStreamReader isr = new InputStreamReader(is, charset);
BufferedReader br = new BufferedReader(isr)) {
char[] buf = new char[1024];
int len;
while ((len = br.read(buf)) != -1) {
sb.append(buf, 0, len);
}
}
return sb.toString();
}
public class FileIOExample {
public static void main(String[] args) {
String src = "src.txt", dest = "dest.txt";
// 字節流複製(圖片/二進制通用)
copyFileByStream(src, dest);
// 字符流複製(文本文件)
copyFileByReader(src + ".txt", dest + ".txt");
}
// 字節流複製模板
static void copyFileByStream(String src, String dest) {
try (InputStream in = new BufferedInputStream(new FileInputStream(src));
OutputStream out = new BufferedOutputStream(new FileOutputStream(dest))) {
byte[] buf = new byte[8192];
int len;
while ((len = in.read(buf)) != -1) out.write(buf, 0, len);
out.flush();
} catch (IOException e) { throw new UncheckedIOException(e); }
}
// 字符流複製模板
static void copyFileByReader(String src, String dest) {
try (Reader in = new BufferedReader(new InputStreamReader(new FileInputStream(src), StandardCharsets.UTF_8));
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(dest), StandardCharsets.UTF_8))) {
char[] buf = new char[8192];
int len;
while ((len = in.read(buf)) != -1) out.write(buf, 0, len);
out.flush();
} catch (IOException e) { throw new UncheckedIOException(e); }
}
}
try-with-resources 強制自動關閉,拒絕手動 finally 易漏關。InputStreamReader/OutputStreamWriter 時顯式傳 StandardCharsets.UTF_8,避免跨平台亂碼。BufferedInputStream/OutputStream 或 BufferedReader/Writer,減少系統調用次數,性能提升數量級。readAllBytes() 導致 OOM,採用固定緩衝區循環讀寫。Files.newBufferedReader()、Files.copy()、FileChannel 等現代 API。Java IO 體系雖大,掌握「四大基類 → 裝飾者模式組合 → 轉換流橋樑 → 緩衝優化」這條主線,配合 try-with-resources 模板化編碼,即可應對 95% 以上業務場景。建議收藏代碼模板,用時拿來即用。