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

J2ME 中文亂碼終極解決方案:UTF-8 編碼統一與 DataInput/OutputStream 實戰

     編輯:J2ME

亂碼根因:編碼不一致

J2ME 中文問題的本質在於寫入與讀取時使用的字元編碼不匹配。根據 MIDP 規範,所有支援 J2ME 的裝置強制支援 UTF-8,因此統一採用 UTF-8 進行字串與位元組陣列互轉,即可徹底解決儲存記錄集(RMS)、網路傳輸、資源檔讀取等場景的中文亂碼問題。

錯誤示範:平台預設編碼陷阱

直接使用 String.getBytes() 或 new String(byte[]) 會依賴平台預設編碼(通常為 ISO-8859-1),導致中文資料損壞:

// ❌ 錯誤做法
byte[] data = "中文".getBytes();        // 平台預設編碼
String s = new String(data);            // 平台預設解碼

標準解法:DataOutputStream / DataInputStream + UTF-8

DataOutputStream.writeUTF() 與 DataInputStream.readUTF() 內建採用修改版 UTF-8(Modified UTF-8),是 J2ME 處理中文的標準方式:

import java.io.*;

public final class ChineseCodec {
    private ChineseCodec() {} // 工具類禁止實例化

    /** 字串 → 位元組陣列 (UTF-8) */
    public static byte[] toBytes(String s) {
        if (s == null) return new byte[0];
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            DataOutputStream dos = new DataOutputStream(baos);
            dos.writeUTF(s);           // 寫入修改版 UTF-8
            dos.flush();
            return baos.toByteArray();
        } catch (IOException e) {
            throw new RuntimeException("UTF-8 編碼失敗", e);
        }
    }

    /** 位元組陣列 → 字串 (UTF-8) */
    public static String toString(byte[] bytes) {
        if (bytes == null || bytes.length == 0) return "";
        try {
            ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
            DataInputStream dis = new DataInputStream(bais);
            return dis.readUTF();      // 讀取修改版 UTF-8
        } catch (IOException e) {
            throw new RuntimeException("UTF-8 解碼失敗", e);
        }
    }
}

應用場景實戰

1. RMS 記錄儲存

// 寫入
RecordStore rs = RecordStore.openRecordStore("UserData", true);
byte[] data = ChineseCodec.toBytes("玩家名稱: 王小明");
rs.addRecord(data, 0, data.length);

// 讀取
byte[] record = rs.getRecord(recordId);
String text = ChineseCodec.toString(record); // 正確還原中文

2. HTTP 網路傳輸

HttpConnection conn = (HttpConnection) Connector.open(url);
conn.setRequestMethod(HttpConnection.POST);
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");

OutputStream os = conn.openOutputStream();
os.write(ChineseCodec.toBytes("msg=中文訊息&id=123"));
os.flush();

3. 資源檔讀取

InputStream is = getClass().getResourceAsStream("/res/config.txt");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int len;
while ((len = is.read(buf)) > 0) baos.write(buf, 0, len);
String content = ChineseCodec.toString(baos.toByteArray());

注意事項

  • 修改版 UTF-8 差異:J2ME 的 writeUTF/readUTF 將 \\u0000 編碼為兩位元組 0xC0 0x80,而非標準 UTF-8 的單一 0x00。雙端必須同為 J2ME 或同用 DataInput/OutputStream 才能互通。
  • 避免手動編碼:不要自行實作 UTF-8 編解碼,效能差且易出錯,內建類別經過 JVM 優化。
  • 資源檔編碼:確保專案原始碼與資源檔均以 UTF-8 儲存(IDE 設定 File Encoding = UTF-8)。

總結

統一使用 DataOutputStream.writeUTF() / DataInputStream.readUTF() 處理所有字串↔位元組轉換,是 J2ME 中文問題的唯一標準解。拒絕 getBytes()、new String(bytes)、String.getBytes("UTF-8") 等非標準寫法,即可在 RMS、網路、資源檔全場景實現中文零亂碼。

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