J2ME (MIDP) 無 InputStreamReader 支援自定義字符集,讀取 Unicode (UTF-16) 或 UTF-8 文件需手動解碼。本文提供兩個工具方法,直接返回 String。
public static String readUnicode(String resource) {
byte[] buf = new byte[1024];
InputStream is = null;
try {
is = YourMidlet.class.getResourceAsStream(resource);
is.skip(2); // 跳過 BOM (FE FF)
int len = is.read(buf);
StringBuffer sb = new StringBuffer();
for (int i = 0; i + 1 < len; i += 2) {
int low = buf[i] & 0xFF;
int high = buf[i + 1] & 0xFF;
char c = (char) (low | (high << 8)); // UTF-16BE → char
sb.append(c);
}
return sb.toString();
} catch (IOException e) {
e.printStackTrace();
return null;
} finally {
try { if (is != null) is.close(); } catch (IOException ignored) {}
}
}
關鍵點:
FE FF 表示大端),需 skip(2)。char 為 16 位無符號,直接組合高低位即可。public static String readUTF8(String resource) {
byte[] buf = new byte[1024];
InputStream is = null;
try {
is = YourMidlet.class.getResourceAsStream(resource);
int len = is.read(buf);
// MIDP 2.0 支援 "UTF-8" 字符集名稱
return new String(buf, 0, len, "UTF-8");
} catch (IOException e) {
e.printStackTrace();
return null;
} finally {
try { if (is != null) is.close(); } catch (IOException ignored) {}
}
}
注意:
new String(bytes, "UTF-8") 依賴平台實現,MIDP 2.0 強制支援 UTF-8,MIDP 1.0 可能拋出 UnsupportedEncodingException。ByteArrayOutputStream 累積。public static String readText(String resource, String encoding) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream is = YourMidlet.class.getResourceAsStream(resource);
if (is == null) throw new IOException("Resource not found: " + resource);
byte[] buf = new byte[512];
int len;
while ((len = is.read(buf)) != -1) baos.write(buf, 0, len);
is.close();
if ("Unicode".equalsIgnoreCase(encoding) || "UTF-16".equalsIgnoreCase(encoding)) {
byte[] data = baos.toByteArray();
if (data.length >= 2 && data[0] == (byte)0xFE && data[1] == (byte)0xFF) {
// 跳過 BOM
byte[] trimmed = new byte[data.length - 2];
System.arraycopy(data, 2, trimmed, 0, trimmed.length);
data = trimmed;
}
StringBuffer sb = new StringBuffer();
for (int i = 0; i + 1 < data.length; i += 2) {
sb.append((char)((data[i] & 0xFF) | ((data[i+1] & 0xFF) << 8)));
}
return sb.toString();
} else {
return baos.toString(encoding); // UTF-8, ISO-8859-1 等
}
}
J2ME 讀取多編碼文本核心在於:手動處理 BOM、位操作組合 char、分塊累積大文件。封裝通用工具類後,業務代碼僅需一行調用。