我正在尝试找到一个子字符串方法或 characterAt 方法,该方法适用于在 JAVA 中包含 UTF-8 编码文本的字符串。
在内部,JAVA 使用 UTF-16。这意味着字符串由大小为 2 个字节的字符组成。一个 UTF-8 字符的大小最多为 6 个字节。当 JAVA 将其存储在字符串中时,它将 UTF-8 字符拆分为多个字符。
例如:字符 U+20000(UTF-8 Hex:F0 A0 80 80)在 JAVA 内部存储为带有两个字符(UTF-16 Hex:D840 和 DC00)的字符串。
当您有一个包含 4 字节 UTF-8 字符的字符串并使用长度时,答案是“2”。当您使用 substring(0,1) 时,您将获得字符的前半部分。
一些代码来说明这一点:
ByteBuffer inputBuffer = ByteBuffer.wrap(new byte[]{(byte)0xF0, (byte)0xA0, (byte)0x80, (byte)0x80});
CharBuffer data = Charset.forName("UTF-8").decode(inputBuffer);
String string_test = data.toString();
int length = string_test.length();
String first_half = string_test.substring(0, 1);
String second_half = string_test.substring(1, 2);
String full_character = string_test.substring(0, 2);
所有这一切,即使出乎意料,也不是错误,因为 JAVA 在 UTF-16 中工作。固有的 UTF-8 支持会很好。但它不存在。
JAVA 在默认库中是否有任何类,或者是否存在某个提供 UTF-8 支持的类?如:
- utf8string.length() - 如果其中有一个 4 字节字符,
则 返回 1 - utf8string.getCharacterAt(0) - 返回第一个字符,而不是前半部分。
- utf8string.substring(0,1) - 返回第一个字符,而不是前半部分。
或者,对此常用的解决方案是什么?读取 UTF-8 文件时将所有非 UTF-16 支持的 UTF-8 字符转换为默认的 UTF-16 字符?结果,丢失了 UTF-16 不支持的代码点范围内的所有字符信息?这在我的具体实现中不一定是一个问题,所以如果有一种通用的方法可以做到这一点,我会感兴趣。