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

J2ME 中文編碼終極解決方案:網絡傳輸、RMS 存儲、資源文件讀取三大場景 UTF-8 最佳實踐

     編輯:J2ME

核心原則:統一使用 UTF-8

Java 內部字符串為 UTF-16 (char 2 字節)。J2ME 環境下,為了節省頻寬、存儲空間並兼容中英文混排,**所有外部交互 (網絡、文件、RMS) 均採用 UTF-8 編碼** 是行業標準做法。

場景一:網絡傳輸中文 (Socket / HTTP)

錯誤做法:直接用 OutputStream.write(bytes[]) / InputStream.read(bytes[]) 按字節傳輸,編碼不一致導致亂碼。

正確做法:封裝為 DataOutputStream / DataInputStream,使用 writeUTF(String) / readUTF()。

客戶端發送

SocketConnection conn = (SocketConnection) Connector.open("socket://server:port");
DataOutputStream dos = conn.openDataOutputStream();
dos.writeInt(msgType);      // 先寫 int
dos.writeByte(subType);     // 再寫 byte
dos.writeUTF(chineseText);  // 最後寫 UTF-8 字符串 (含長度前綴)
dos.flush();

服務端接收 (順序必須完全一致)

DataInputStream dis = conn.openDataInputStream();
int type = dis.readInt();
byte sub = dis.readByte();
String text = dis.readUTF();  // 自動解碼 UTF-8

HTTP POST 發送中文參數

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();
// 手動構造 application/x-www-form-urlencoded 體,值需 URLEncoder.encode(str, "UTF-8")
String body = "param=" + URLEncoder.encode(chineseText, "UTF-8");
os.write(body.getBytes("UTF-8"));  // MIDP 可能無 getBytes(encoding),需手動轉碼或用 DataOutputStream
os.flush();

注意:MIDP 無 java.net.URLEncoder,需自行實現或使用第三方輕量庫。

場景二:RMS 持久化存儲中文

RMS 只接受 byte[]。流程:String → UTF-8 byte[] → 存入 RecordStore → 讀出 byte[] → UTF-8 String。

寫入

RecordStore rs = RecordStore.openRecordStore("MyData", true);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
dos.writeUTF(chineseString);  // 關鍵:writeUTF 自動處理 UTF-8 編碼 + 長度前綴
byte[] data = baos.toByteArray();
rs.addRecord(data, 0, data.length);
dos.close();
baos.close();

讀取

byte[] data = rs.getRecord(recordId);
ByteArrayInputStream bais = new ByteArrayInputStream(data);
DataInputStream dis = new DataInputStream(bais);
String restored = dis.readUTF();  // 自動解碼
dis.close();
bais.close();

場景三:讀取 JAR 內資源文件 (含中文)

步驟:

  1. 文本編輯器 (UltraEdit/Notepad++/VS Code) 將文件另存為 UTF-8 無 BOM 編碼
  2. 放入項目 res/ 目錄,打包進 JAR
  3. 代碼中以 二進制流讀取 → 指定 UTF-8 解碼

通用讀取工具方法


public String readResourceAsUTF8(String resourcePath) {
    InputStream is = getClass().getResourceAsStream(resourcePath);
    if (is == null) return null;
    try {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len;
        while ((len = is.read(buffer)) != -1) {
            baos.write(buffer, 0, len);
        }
        byte[] data = baos.toByteArray();
        // 關鍵:指定 UTF-8 解碼 (MIDP 支持 String(byte[], String encoding))
        return new String(data, "UTF-8");
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    } finally {
        try { is.close(); } catch (Exception ignored) {}
    }
}

調用示例


// 讀取 res/config.txt (UTF-8 編碼)
String config = readResourceAsUTF8("/config.txt");
// 讀取 res/messages_zh.properties
String msg = readResourceAsUTF8("/messages_zh.properties");

常見坑點總結表

場景錯誤現象根因修正
網絡傳輸中文亂碼/截斷直接 write(bytes) 無編碼協議DataOutputStream.writeUTF / readUTF
HTTP 參數服務端收到亂碼未 URLEncode 或編碼不一致手動 UTF-8 URLEncode + Content-Type charset=UTF-8
RMS 存儲讀出亂碼String.getBytes() 使用平台默認編碼DataOutputStream.writeUTF / DataInputStream.readUTF
資源文件讀出亂碼文件非 UTF-8 / 讀取未指定編碼文件存 UTF-8 無 BOM + new String(bytes, "UTF-8")
跨平台模擬器正常、實機亂碼實機默認編碼非 UTF-8 (如 GBK)所有外部交互強制指定 UTF-8

進階:自定義輕量級 UTF-8 編解碼器 (無 DataOutputStream 時)

極少數精簡設備可能缺失 DataOutputStream,可自行實現:


// 簡易 UTF-8 編碼 (僅供參考,生產建議用標準庫)
public static byte[] encodeUTF8(String s) {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    for (int i = 0; i < s.length(); i++) {
        char c = s.charAt(i);
        if (c <= 0x7F) {
            baos.write(c);
        } else if (c <= 0x7FF) {
            baos.write(0xC0 | (c >> 6));
            baos.write(0x80 | (c & 0x3F));
        } else {
            baos.write(0xE0 | (c >> 12));
            baos.write(0x80 | ((c >> 6) & 0x3F));
            baos.write(0x80 | (c & 0x3F));
        }
    }
    return baos.toByteArray();
}

總結

J2ME 中文處理鐵律:**內部 Unicode (char/String) → 外部統一 UTF-8**。三大場景通用模板:DataOutputStream.writeUTF / DataInputStream.readUTF (網絡/RMS) + new String(bytes, "UTF-8") (資源文件)。文件源碼編輯器務必設置為 UTF-8 無 BOM,徹底杜絕亂碼。

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