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

Java IO 裝飾流核心實戰:DataInputStream/OutputStream 實現結構化數據讀寫

     編輯:Java 相關知識

從「手動拼裝 byte[]」到「結構化讀寫」

基礎 IO 只認 byte[]/char[],寫入 int、String、陣列需手動轉換、協議設計,極易出錯。DataInputStream / DataOutputStream 封裝了標準二進制格式,提供 readInt()/writeInt()、readUTF()/writeUTF() 等類型安全方法,實現「寫什麼讀什麼,順序一致即可」。

核心規則:成對使用,順序嚴格對應

⚠️ 鐵律:DataOutputStream 寫入的格式,只能 用 DataInputStream 按完全相同的順序、類型讀取。任何順序/類型不匹配都會導致資料錯位或 EOFException。

完整實戰:自定義資料物件持久化

1. 定義資料模型


public class MyData {
    boolean flag;
    int number;
    String text;
    short[] scores;
    
    public MyData() {}
    public MyData(boolean flag, int number, String text, short[] scores) {
        this.flag = flag; this.number = number; this.text = text; this.scores = scores;
    }
}

2. 寫入:建立檔案格式協議


import java.io.*;

public class WriteFileUseDataStream {
    public static void main(String[] args) {
        short[] scores = {1, 3, 134, 12};
        MyData data = new MyData(true, 100, "Java語言", scores);
        writeFile(data);
    }
    
    public static void writeFile(MyData data) {
        // try-with-resources 自動關閉
        try (FileOutputStream fos = new FileOutputStream("test.my");
             DataOutputStream dos = new DataOutputStream(fos)) {
            
            // 協議順序:flag → number → text → array_length → array_elements
            dos.writeBoolean(data.flag);
            dos.writeInt(data.number);
            dos.writeUTF(data.text); // UTF-8 編碼 + 長度前綴
            
            // 陣列寫入協議:先長度,再逐元素
            dos.writeInt(data.scores.length);
            for (short s : data.scores) {
                dos.writeShort(s);
            }
            System.out.println("寫入完成,檔案格式已固化");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

3. 讀取:嚴格遵循寫入協議


import java.io.*;

public class ReadFileUseDataStream {
    public static void main(String[] args) {
        MyData data = readFile();
        System.out.println("flag: " + data.flag);
        System.out.println("number: " + data.number);
        System.out.println("text: " + data.text);
        for (short s : data.scores) System.out.print(s + " ");
    }
    
    public static MyData readFile() {
        MyData data = new MyData();
        try (FileInputStream fis = new FileInputStream("test.my");
             DataInputStream dis = new DataInputStream(fis)) {
            
            // 嚴格按寫入順序讀取
            data.flag = dis.readBoolean();
            data.number = dis.readInt();
            data.text = dis.readUTF();
            
            int len = dis.readInt(); // 讀取陣列長度
            data.scores = new short[len];
            for (int i = 0; i < len; i++) {
                data.scores[i] = dis.readShort();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return data;
    }
}

DataOutputStream 寫入格式細節(透明協議)

方法二進制格式說明
writeBoolean1 byte (0/1)
writeByte/Short/Int/Long1/2/4/8 bytes大端序
writeFloat/Double4/8 bytesIEEE 754
writeUTF2 bytes 長度 + UTF-8 bytes長度限 65535,長字串用 writeString
writeChars每 char 2 bytes不寫長度,需預知長度

進階應用:記憶體陣列作為數據源

Data 流不綁定檔案,可搭配 ByteArrayOutputStream/InputStream 實現物件↔byte[] 雙向轉換:


// 序列化到 byte[]
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (DataOutputStream dos = new DataOutputStream(baos)) {
    dos.writeInt(123);
    dos.writeUTF("Hello");
}
byte[] bytes = baos.toByteArray(); // 可網路傳輸、存 Redis 等

// 從 byte[] 反序列化
try (DataInputStream dis = new DataInputStream(new ByteArrayInputStream(bytes))) {
    int n = dis.readInt(); // 123
    String s = dis.readUTF(); // Hello
}

常見陷阱與避坑指南

  1. 順序錯位:寫入順序變更、欄位增減未同步讀取端 → 版本號機制或遷移腳本。
  2. UTF 長度溢出:字串超過 64KB → writeUTF 拋出 UTFDataFormatException,改用 writeBytes+長度或 ObjectOutputStream。
  3. 跨語言互操作:Data 流為 Java 專用格式,異構系統請用 Protobuf、Avro、JSON。
  4. 忘記關閉流:資料留在緩衝區未刷新 → try-with-resources 強制關閉。

總結

DataInputStream/OutputStream 以標準二進制協議屏蔽了手動 byte[] 操作的複雜性,是 Java 內部儲存、進程間通訊、簡易序列化的利器。核心心法:**協議先行,順序為王,成對使用,自動關閉**。

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