| 編碼 | Hex 數據 | 特徵 | 中文佔用 |
|---|---|---|---|
| ANSI (GBK/GB2312) | C4 A6 CD D0 C2 DE C0 AD | 無 BOM,每字節 > 0x80 | 2 字節 |
| Unicode (UTF-16LE) | FF FE 69 64 58 62 57 7F C9 62 | BOM: FF FE,固定 2 字節/字符 | 2 字節 |
| UTF-8 | EF BB BF E6 91 A9 E6 89 98 E7 BD 97 E6 8B 89 | BOM: EF BB BF,英文 1 字節,中文 3 字節 | 3 字節 |
J2ME 環境下,直接操作中文 String 進行 RMS 存儲、網絡傳輸、System.out.println 調試,極易出現亂碼。根因:
// 寫入: String -> byte[] (Modified UTF-8)
public static byte[] stringToBytes(String s) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
dos.writeUTF(s); // 寫入長度(2字節) + Modified UTF-8 字節
return baos.toByteArray();
} catch (IOException e) { return null; }
}
// 讀取: byte[] -> String
public static String bytesToString(byte[] b, int offset, int len) {
try {
ByteArrayInputStream bais = new ByteArrayInputStream(b, offset, len);
DataInputStream dis = new DataInputStream(bais);
return dis.readUTF(); // 解析 Modified UTF-8
} catch (IOException e) { return null; }
}
關鍵點:writeUTF/readUTF 使用 Modified UTF-8 (補碼長度前綴),寫讀必須配對使用,不可與標準 UTF-8 混用。
// 存
byte[] data = stringToBytes(lrcText);
recordStore.addRecord(data, 0, data.length);
// 取
byte[] data = recordStore.getRecord(recordId);
String lrc = bytesToString(data, 0, data.length);
// 發送端
byte[] payload = stringToBytes(text);
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());
模擬器/真機控制台編碼通常為平台默認 (如 GBK、Cp1252),而 Java 內部 String 為 UTF-16。直接打印會經過 JVM 默認編碼轉換,導致不可讀。
| 發送端 getBytes 參數 | 接收端 byte[] 內容 | 模擬器屏幕顯示 | 控制台 System.out |
|---|---|---|---|
| 無參數 (平台默認) | 12 bytes,每漢字 2 bytes,值為 ANSI 編碼 | 亂碼 | ✅ 正常 |
| "ISO10646" | 拋出 UnsupportedEncodingException | — | — |
| "ISO8859_1" | 6 bytes,全 0x3F ('?') | 全問號 | 全問號 |
g.drawString(str, x, y, 0),LCDUI 內部處理字體渲染,最直觀。for(byte b: str.getBytes()) System.out.print(Integer.toHexString(b&0xFF)+" ");,觀察原始字節排查編碼。DataOutputStream.writeUTF / DataInputStream.readUTF (Modified UTF-8),寫讀配對,跨平台無亂碼。String.getBytes() 發送、new String(byte[]) 解析、混用多種編碼參數。