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

Java IO 進階筆記(三):轉換流、數據流與字節數組流深度解析

     編輯:Java 相關知識

前言

Java IO 體系中,轉換流橋接字節與字符世界,數據流實現基本類型的二進制序列化,字節數組流提供內存級高速數據交換。本文通過源碼分析與實戰代碼,深度解析這三類流的核心機制與最佳實踐。

一、轉換流:字節與字符的橋樑

核心類

  • InputStreamReader:字節輸入流 → 字符輸入流
  • OutputStreamWriter:字節輸出流 → 字符輸出流

關鍵特性

  • 支持指定字符編碼(構造函數參數),解決中文亂碼核心方案
  • 可裝飾 BufferedReader/Writer 獲得緩衝與行級操作(readLine()/newLine())
  • 獲取當前編碼:getEncoding()

實戰:指定編碼寫入文件

try (FileOutputStream fos = new FileOutputStream("test_gbk.txt");
     OutputStreamWriter osw = new OutputStreamWriter(fos, "GBK")) {
    osw.write("轉換流練習:指定GBK編碼");
    osw.flush();
    System.out.println("實際編碼:" + osw.getEncoding()); // 輸出:GBK
}

實戰:控制台輸入讀取

try (InputStreamReader isr = new InputStreamReader(System.in);
     BufferedReader br = new BufferedReader(isr)) {
    String line;
    while ((line = br.readLine()) != null) {
        if ("exit".equals(line)) break;
        System.out.println("輸入:" + line);
    }
}

二、數據流:基本類型的二進制序列化

核心類

  • DataInputStream / DataOutputStream
  • 繼承自 InputStream/OutputStream,屬於處理流(裝飾器模式)

支持的數據類型

類型寫入方法讀取方法
booleanwriteBoolean()readBoolean()
bytewriteByte()readByte()
charwriteChar()readChar()
shortwriteShort()readShort()
intwriteInt()readInt()
longwriteLong()readLong()
floatwriteFloat()readFloat()
doublewriteDouble()readDouble()
StringwriteUTF()readUTF()

關鍵特性

  • 平台無關性:使用大端序(網絡字節序)存儲,跨平台一致
  • 順序敏感:讀取順序必須與寫入順序完全一致
  • available() 可獲取剩餘可讀字節數

實戰:內存中基本類型序列化

try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
     DataOutputStream dos = new DataOutputStream(baos);
     ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
     DataInputStream dis = new DataInputStream(bais)) {

    dos.writeDouble(Math.random());
    dos.writeBoolean(true);
    dos.flush();

    System.out.println("可讀字節:" + dis.available()); // 9 = 8(double) + 1(boolean)
    System.out.println("讀取 double:" + dis.readDouble());
    System.out.println("讀取 boolean:" + dis.readBoolean());
}
// 輸出示例:
// 可讀字節:9
// 讀取 double:0.02241410199042526
// 讀取 boolean:true

三、字節數組流:內存級高速數據通道

核心類

  • ByteArrayInputStream:從內存字節數組讀取
  • ByteArrayOutputStream:向內存字節數組寫入

構造函數選擇

類構造函數適用場景
ByteArrayInputStreamnew ByteArrayInputStream(byte[] buf)讀取現有數組
new ByteArrayInputStream(byte[] buf, int offset, int length)讀取數組片段
ByteArrayOutputStreamnew ByteArrayOutputStream()默認 32 字節,自動擴容
new ByteArrayOutputStream(int size)預分配指定大小,減少擴容開銷

核心方法

  • toByteArray():獲取內部緩衝區副本(ByteArrayOutputStream)
  • toString() / toString(String charset):直接轉字符串
  • writeTo(OutputStream out):直接輸出到其他流,避免中間拷貝
  • reset():重置緩衝區,復用對象

實戰:流之間的數據傳遞

// 輸出流數據直接接入輸入流
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (DataOutputStream dos = new DataOutputStream(baos)) {
    dos.writeUTF("Hello Memory Stream");
    dos.writeInt(2024);
}

byte[] data = baos.toByteArray();
try (ByteArrayInputStream bais = new ByteArrayInputStream(data);
     DataInputStream dis = new DataInputStream(bais)) {
    System.out.println(dis.readUTF()); // Hello Memory Stream
    System.out.println(dis.readInt());   // 2024
}

最佳實踐總結

  1. 轉換流:始終顯式指定編碼,避免平台默認編碼差異導致亂碼
  2. 數據流:嚴格保持讀寫順序一致,適合基本類型序列化,不適合複雜對象圖
  3. 字節數組流:內存數據交換首選,預估大小預分配緩衝區,大數據量注意 OOM 風險
  4. 資源管理:統一使用 try-with-resources 確保流正確關閉
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved