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

J2ME 文件讀寫亂碼終極解決:DataOutputStream/InputStream + UTF 統一編碼實踐

     編輯:J2ME

問題現場

音樂歌詞讀寫功能:部分手機正常,部分手機讀取本地文件亂碼。嘗試 new String(bytes, "UTF-8")、DataInputStream.readUTF() 均無效。

根因

寫入與讀取的編碼/API 不一致。J2ME 文件操作本質是字節流,字符編碼轉換完全由開發者控制,任何一端不匹配即亂碼。

統一協議:DataOutputStream.writeUTF / DataInputStream.readUTF

// 寫入文件 (RMS 或 FileConnection)
public synchronized void saveLyricFile(String data, String name) {
    if (data == null || data.length() == 0) return;
    FileConnection fc = null;
    OutputStream os = null;
    DataOutputStream dos = null;
    try {
        fc = (FileConnection) Connector.open("file:///" + savePath + name);
        if (fc.exists()) { fc.close(); return; } // 已存在跳過
        fc.create();
        os = fc.openOutputStream();
        dos = new DataOutputStream(os);
        dos.writeUTF(data); // ★ 關鍵:寫入 Modified UTF-8 (含長度前綴)
        dos.close(); os.close(); fc.close();
    } catch (IOException e) {
        // 統一關閉資源
        closeQuietly(fc); closeQuietly(dos); closeQuietly(os);
    } finally {
        closeQuietly(fc); closeQuietly(dos); closeQuietly(os);
    }
}

// 讀取文件
public String readLyricFile(String name) {
    FileConnection fc = null;
    InputStream is = null;
    DataInputStream dis = null;
    try {
        fc = (FileConnection) Connector.open("file:///" + savePath + name);
        if (!fc.exists()) return null;
        is = fc.openInputStream();
        dis = new DataInputStream(is);
        return dis.readUTF(); // ★ 關鍵:配對讀取 Modified UTF-8
    } catch (IOException e) { return null; }
    finally { closeQuietly(fc); closeQuietly(dis); closeQuietly(is); }
}

為什麼這套方案有效?

  1. writeUTF/readUTF 使用 Modified UTF-8:自帶 2 字節長度前綴,讀取時精確知道字節邊界,無歧義。
  2. 寫讀 API 完全配對:同一套類庫實現,跨設備、跨平台行為一致。
  3. 避開平台默認編碼陷阱:不依賴 System.getProperty("file.encoding") 或平台默認 Charset。

擴展:網絡傳輸同理

// 發送端
byte[] payload = stringToBytes(text); // 內部用 DataOutputStream.writeUTF
Datagram dg = conn.newDatagram(payload, payload.length, addr);
conn.send(dg);

// 接收端
Datagram dg = conn.newDatagram(maxSize);
conn.receive(dg);
String text = bytesToString(dg.getData(), dg.getOffset(), dg.getLength()); // 內部用 DataInputStream.readUTF

資源關閉工具方法 (防止泄漏)

private static void closeQuietly(Connection c) {
    if (c != null) try { c.close(); } catch (IOException ignored) {}
}
private static void closeQuietly(InputStream is) { /* 同理 */ }
private static void closeQuietly(OutputStream os) { /* 同理 */ }

總結原則

  1. 寫入:DataOutputStream.writeUTF(String)
  2. 讀取:DataInputStream.readUTF()
  3. 傳輸:序列化為 byte[] 走字節流,兩端同套編解碼。
  4. 資源管理:finally 塊統一靜默關閉,避免句柄泄漏導致後續操作失敗。

遵循此協議,**文件讀寫、網絡傳輸、RMS 存儲** 全場景中文零亂碼,經大量真機驗證。

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