首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 程式設計學習筆記(三):IO 流體系全景詳解

     編輯:Java 相關知識

前言

IO 流是 Java 處理裝置間數據傳輸的核心抽象。本筆記系統梳理流分類、字符/位元組流轉換、核心類 API、異常處理模式、緩衝與裝飾模式、標準流重定向,並附完整代碼示例,作為學習與複習參考。

一、流分類總覽

維度分類典型類適用場景
按數據單位位元組流InputStream/OutputStream 子類圖片、視頻、二進制文件、網路數據
字符流Reader/Writer 子類文本文件、控制台輸入輸出、字符串處理
按流向輸入流InputStream/Reader從源讀取數據(檔案、網路、鍵盤)
輸出流OutputStream/Writer向目的寫入數據(檔案、網路、螢幕)

核心原則:字符流本質是位元組流經編碼表轉換而來(InputStreamReader/OutputStreamWriter),預設使用平台編碼,跨平台必須顯式指定 UTF-8。

二、字符流核心類與實戰

1. 基礎抽象類

  • Reader:read()、read(char[])、close()。
  • Writer:write(int/char[]/String)、flush()、close()(關閉前自動 flush)。

2. FileReader / FileWriter — 文本文件便捷類

// 寫入(支援續寫 append=true)
try (FileWriter fw = new FileWriter("demo.txt", true)) {
    fw.write("Hello World");
    fw.write("\r\n"); // Windows 換行
} catch (IOException e) { e.printStackTrace(); }

// 讀取:單字符 / 字符陣列
try (FileReader fr = new FileReader("demo.txt")) {
    int ch;
    while ((ch = fr.read()) != -1) System.out.print((char)ch);
    // 或批量讀取
    char[] buf = new char[1024];
    int len;
    while ((len = fr.read(buf)) != -1) System.out.print(new String(buf, 0, len));
}

3. 異常處理標準模式

FileWriter fw = null;
try {
    fw = new FileWriter("demo.txt");
    fw.write("data");
} catch (IOException e) {
    // 處理異常
} finally {
    if (fw != null) try { fw.close(); } catch (IOException ignored) {}
}
// JDK 7+ 推薦 try-with-resources 自動關閉
try (FileWriter fw = new FileWriter("demo.txt")) { fw.write("data"); }

4. 字符流複製文件

try (FileReader fr = new FileReader("src.txt");
     FileWriter fw = new FileWriter("dest.txt")) {
    char[] buf = new char[1024];
    int len;
    while ((len = fr.read(buf)) != -1) fw.write(buf, 0, len);
}

三、緩衝字符流:BufferedReader / BufferedWriter

核心增強

  • BufferedReader.readLine():按行讀取(不含換行符),返回 null 表示結束。
  • BufferedWriter.newLine():跨平台寫入系統換行符(line.separator)。
  • 內部緩衝區(預設 8KB)減少系統調用,大幅提升效率。

緩衝複製文本文件

try (BufferedReader br = new BufferedReader(new FileReader("src.txt"));
     BufferedWriter bw = new BufferedWriter(new FileWriter("dest.txt"))) {
    String line;
    while ((line = br.readLine()) != null) {
        bw.write(line);
        bw.newLine();
    }
}

LineNumberReader

繼承 BufferedReader,提供 getLineNumber()/setLineNumber() 追蹤行號。

四、裝飾模式在 IO 體系中的應用

結構:

  • Component:Reader/Writer、InputStream/OutputStream。
  • ConcreteComponent:FileReader、FileInputStream 等具體源/目的。
  • Decorator:BufferedReader、InputStreamReader、OutputStreamWriter 等包裝類,構造器接收被裝飾對象。

優勢:動態組合功能(緩衝、編碼轉換、行讀取),避免繼承爆炸,符合單一職責與開閉原則。

// 典型組合鏈:文件位元組流 → 編碼轉換 → 緩衝 → 行讀取
BufferedReader br = new BufferedReader(
    new InputStreamReader(
        new FileInputStream("file.txt"), "UTF-8"));

五、位元組流核心類與實戰

FileInputStream / FileOutputStream

// 寫入位元組
try (FileOutputStream fos = new FileOutputStream("data.bin")) {
    fos.write("abc".getBytes()); // 字符串轉位元組陣列
}

// 讀取:單位元組 / 位元組陣列 / available() 獲取剩餘長度
try (FileInputStream fis = new FileInputStream("data.bin")) {
    byte[] buf = new byte[1024];
    int len;
    while ((len = fis.read(buf)) != -1) System.out.write(buf, 0, len);
    // available() 僅適用於文件/管道,網路流不可靠,不建議用於分配大陣列
}

位元組流複製圖片(二進制安全)

try (FileInputStream fis = new FileInputStream("src.jpg");
     FileOutputStream fos = new FileOutputStream("dest.jpg")) {
    byte[] buf = new byte[1024];
    int len;
    while ((len = fis.read(buf)) != -1) fos.write(buf, 0, len);
}

六、緩衝位元組流:BufferedInputStream / BufferedOutputStream

同字符緩衝流,裝飾位元組流提供 8KB 緩衝區,複製大文件效率顯著提升。

try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("src.jpg"));
     BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("dest.jpg"))) {
    byte[] buf = new byte[1024];
    int len;
    while ((len = bis.read(buf)) != -1) bos.write(buf, 0, len);
}

七、轉換流:位元組 ↔ 字符橋梁

  • InputStreamReader(InputStream in, String charset):位元組流 → 字符流,指定編碼。
  • OutputStreamWriter(OutputStream out, String charset):字符流 → 位元組流,指定編碼。

應用場景:指定 UTF-8 讀寫文本、鍵盤輸入按行處理、標準流重定向。

鍵盤輸入按行讀取並轉大寫

try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
     BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out))) {
    String line;
    while ((line = br.readLine()) != null) {
        if ("over".equals(line)) break;
        bw.write(line.toUpperCase());
        bw.newLine();
        bw.flush();
    }
}

八、標準流重定向

System.setIn(InputStream)、System.setOut(PrintStream) 可改變標準輸入/輸出裝置。

// 將鍵盤輸入重定向為文件,控制台輸出重定向為文件 → 實現文件複製
System.setIn(new FileInputStream("src.txt"));
System.setOut(new PrintStream(new FileOutputStream("dest.txt")));
// 此後 System.in 讀取來自 src.txt,System.out 寫入 dest.txt

九、流選擇決策樹(速查)

  1. 源/目的:源→輸入流(InputStream/Reader),目的→輸出流(OutputStream/Writer)。
  2. 數據類型:純文本→字符流(Reader/Writer);二進制→位元組流(InputStream/OutputStream)。
  3. 具體裝置:
    • 硬盤文件→FileInputStream/FileReader、FileOutputStream/FileWriter。
    • 鍵盤→System.in(位元組)→轉換→BufferedReader。
    • 控制台→System.out(位元組)→轉換→BufferedWriter/PrintStream。
    • 內存→ByteArrayInputStream/StringReader、ByteArrayOutputStream/StringWriter。
    • 網路→Socket.getInputStream()/getOutputStream()。
  4. 需不需高效/進階功能:是→套 BufferedInputStream/BufferedReader、BufferedOutputStream/BufferedWriter;需指定編碼→套 InputStreamReader/OutputStreamWriter。

十、指定編碼寫入文件最佳實踐

try (BufferedWriter bw = new BufferedWriter(
        new OutputStreamWriter(new FileOutputStream("utf8.txt"), "UTF-8"))) {
    bw.write("中文測試");
    bw.newLine();
}

FileWriter 無法指定編碼(固定平台預設),必須通過 OutputStreamWriter 包裝 FileOutputStream 實現。

總結

Java IO 體系雖類繁多,但遵循「源/目的 → 數據類型 → 裝置 → 功能增強」四步選型法則,配合裝飾模式動態組合,即可應對所有讀寫場景。重點掌握:字符流處理文本(指定 UTF-8)、位元組流處理二進制、緩衝流提升效率、轉換流橋接編碼、try-with-resources 保證資源釋放。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved