在JAVA中具有2+字节的UTF8字符串的子字符串或characterAt方法

时间:2013-07-08 10:32:50

标签: java encoding utf-8 utf-16

我正在尝试查找子字符串方法或characterAt方法,该方法适用于JAVA中包含UTF-8编码文本的字符串。

在内部,JAVA使用UTF-16。这意味着String由大小为2个字节的字符组成。 UTF-8字符的大小最多为6个字节。当JAVA将其存储在String中时,它会将UTF-8字符分割为多个字符。

例如: 字符U + 20000(UTF-8十六进制:F0 A0 80 80)作为带有两个字符的字符串(UTF-16十六进制:D840和DC00)存储在JAVA内部。

当你有一个包含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不支持的代码点范围内的所有字符信息?这在我的具体实现中不一定是个问题,所以如果有一个共同的方法,我会感兴趣。

2 个答案:

答案 0 :(得分:8)

  

JAVA在默认库中是否有任何类,或者某个类是否存在提供UTF-8支持的类?

你真的不支持UTF-8。你是在Unicode代码点(普通的32位整数)之后,而不是UTF-16代码单元。是的,Java提供了对此的支持,但它并非非常易于使用。

例如,要获取特定代码点,请使用String.codePointAt - 请注意,您提供的索引是以UTF-16代码单位表示的,不是代码点。< / p>

要在代码点中查找长度,请使用String.codePointCount

要查找子字符串,您需要根据UTF-16代码单位查找偏移量,然后使用普通的substring方法;使用String.offsetByCodePoints找到正确的索引。

基本上查看包含String的所有方法的codePoint API。

答案 1 :(得分:0)

您应该寻找的是Java对UTF-32的原生支持。查看String#*codePoint*方法,例如codePointAt