Java IO 是 Java 核心類庫中最基礎、也是最龐大的子系統之一。掌握其設計哲學(裝飾器模式)、流分類體系及核心類用法,是高效處理文件、網絡、內存數據的關鍵。本文系統梳理 Java IO 核心知識點,並附帶實戰代碼模板。
流 是對數據傳輸過程的抽象,代表「有能力產出數據的源」或「有能力接收數據的終點」。
read())。write())。| 維度 | 字節流 | 字符流 |
|---|---|---|
| 基本單位 | Byte (8 bit) | Char (16 bit, UTF-16) |
| 頂級父類 | InputStream / OutputStream | Reader / Writer |
| 適用場景 | 圖片、視頻、二進制文件、網絡傳輸 | 文本文件、字符串處理 |
| 核心橋梁 | InputStreamReader / OutputStreamWriter(指定 Charset) | |
原則:字節流是萬能的(一切皆字節),字符流是為了處理文本而生的便利封裝。
FileInputStream、FileReader)。new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"))。InputStream (抽象) ├── FileInputStream // 文件輸入 ├── ByteArrayInputStream // 內存字節數組輸入 ├── PipedInputStream // 管道輸入(線程間通信) ├── ObjectInputStream // 對象反序列化 ├── FilterInputStream (裝飾器基類) │ ├── BufferedInputStream // 緩沖輸入(關鍵:mark/reset) │ ├── DataInputStream // 基本類型讀取 (readInt, readUTF...) │ └── PushbackInputStream // 回退一字節 └── SequenceInputStream // 多流串聯 OutputStream (抽象) ├── FileOutputStream ├── ByteArrayOutputStream // 內存輸出,toByteArray() ├── PipedOutputStream ├── ObjectOutputStream // 對象序列化 ├── FilterOutputStream │ ├── BufferedOutputStream // 緩沖輸出 │ ├── DataOutputStream // 基本類型寫入 │ └── PrintStream // System.out 本質
Reader (抽象) ├── FileReader // 便捷類,默認編碼 ├── BufferedReader // 緩沖讀取,核心方法 readLine() ├── InputStreamReader // 字節→字符橋梁(指定編碼) ├── StringReader // 字符串源 ├── PipedReader ├── LineNumberReader // 帶行號 └── PushbackReader Writer (抽象) ├── FileWriter ├── BufferedWriter // 緩沖寫入,newLine() ├── OutputStreamWriter // 字符→字節橋梁 ├── PrintWriter // 格式化打印,不拋異常 ├── StringWriter // 輸出到字符串 └── CharArrayWriter
public static String readFile(String path) throws IOException {
try (BufferedReader br = new BufferedReader(
new InputStreamReader(new FileInputStream(path), StandardCharsets.UTF_8))) {
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line).append(System.lineSeparator());
}
return sb.toString();
}
}
public static void writeFile(String path, String content) throws IOException {
try (PrintWriter pw = new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(new FileOutputStream(path), StandardCharsets.UTF_8)))) {
pw.print(content);
}
}
public static void copyBinary(String src, String dest) throws IOException {
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(src));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(dest))) {
byte[] buffer = new byte[8192]; // 8KB
int len;
while ((len = bis.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
}
}
// 寫對象 (要求實現 Serializable)
public static void writeObject(Serializable obj, String file) throws IOException {
try (ObjectOutputStream oos = new ObjectOutputStream(
new BufferedOutputStream(new FileOutputStream(file)))) {
oos.writeObject(obj);
}
}
// 讀對象
public static Object readObject(String file) throws IOException, ClassNotFoundException {
try (ObjectInputStream ois = new ObjectInputStream(
new BufferedInputStream(new FileInputStream(file)))) {
return ois.readObject();
}
}
// String -> byte[] (指定編碼)
byte[] bytes = str.getBytes(StandardCharsets.UTF_8);
// byte[] -> String
String str = new String(bytes, StandardCharsets.UTF_8);
// 內存流管道示例
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (PrintWriter pw = new PrintWriter(baos)) {
pw.println("Hello Memory");
}
byte[] data = baos.toByteArray();
FileInputStream 逐字節讀寫極慢,外層包裹 BufferedInputStream/OutputStream 或 BufferedReader/Writer。InputStreamReader/OutputStreamWriter 時顯式指定 StandardCharsets.UTF_8,避免跨平台亂碼。readAllBytes() 導致 OOM,採用流式分塊處理或 NIO FileChannel + MappedByteBuffer(零拷貝)。Serializable 的類務必顯式聲明 serialVersionUID。Java IO 雖類繁多,但核心邏輯清晰:源頭/終點(節點流)+ 功能增強(處理流/裝飾器)。掌握四大抽象基類、橋梁轉換類、緩沖類、數據類型讀寫類,即可應對 90% 業務場景。現代項目中,NIO.2 (Files, Paths) 和第三方庫(Apache Commons IO, Google Guava)提供了更便捷的高級 API,建議作為首選,底層原理仍是本文所述經典 IO 模型。