音樂歌詞讀寫功能:部分手機正常,部分手機讀取本地文件亂碼。嘗試 new String(bytes, "UTF-8")、DataInputStream.readUTF() 均無效。
寫入與讀取的編碼/API 不一致。J2ME 文件操作本質是字節流,字符編碼轉換完全由開發者控制,任何一端不匹配即亂碼。
// 寫入文件 (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); }
}
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) { /* 同理 */ }
DataOutputStream.writeUTF(String)DataInputStream.readUTF()byte[] 走字節流,兩端同套編解碼。finally 塊統一靜默關閉,避免句柄泄漏導致後續操作失敗。遵循此協議,**文件讀寫、網絡傳輸、RMS 存儲** 全場景中文零亂碼,經大量真機驗證。