繁体   English   中英

为什么我不能在Java的char数组中存储日语UTF-8字符?

[英]Why can't I store Japanese UTF-8 characters in char array in Java?

我有一个字符串“ 1234567(Asics(アicsックス“ーキング))”。 它具有unicode字符,有些是ASCII的一部分,有些则不是。 Java所做的是,ASCII字符占用一个字节,其他Unicode字符占用两个字节。

我的程序的某些部分无法处理这种格式的字符串。 所以我想将值编码为转义序列。

所以字符串

“ 1234567(Asics(アicsックスワーキング))”

将映射到

“\\ u0031 \\ u0032 \\ u0033 \\ u0034 \\ u0035 \\ u0036 \\ u0037 \\ u0028 \\ u0041 \\ u0073 \\ u0069 \\ u0063 \\ u0073 \\ u0020 \\ u0028 \\ u30a2 \\ u30b7 \\ u30c3 \\ u30af \\ u30b9 \\ u30ef \\ u30fc \\ u30ad \\ u30f3 \\ u30b0 \\ u0029 \\ u0020 \\ u0029"

我写了这个功能来做到这一点:-

public static String convertToEscaped(String utf8) throws java.lang.Exception
    {
    char[] str = utf8.toCharArray();
    StringBuilder unicodeStringBuilder = new StringBuilder();
    for(int i = 0; i < str.length; i++){
    char charValue = str[i];
    int intValue = (int) charValue;
    String hexValue = Integer.toHexString(intValue);
    unicodeStringBuilder.append("\\u");
    for (int length = hexValue.length(); length < 4; length++) {
        unicodeStringBuilder.append("0");
    }
    unicodeStringBuilder.append(hexValue);
    }
    return unicodeStringBuilder.toString();
    }

这在我的程序外部运行正常,但在程序内部引起了问题。 这是行char[] str = utf8.toCharArray();发生的情况char[] str = utf8.toCharArray(); 我不知何故失去了我的日语unicode字符,这是因为t在char数组中将这些字符分成2个。

因此,我决定改用byte []

    public static String convertToEscaped(String utf8) throws java.lang.Exception
    {
    byte str[] = utf8.getBytes();
    StringBuilder unicodeStringBuilder = new StringBuilder();
    for(int i = 0; i < str.length - 1 ; i+=2){
    int intValue = (int) str[i]* 256 + (int)str[i+1];
    String hexValue = Integer.toHexString(intValue);
    unicodeStringBuilder.append("\\u");
    for (int length = hexValue.length(); length < 4; length++) {
        unicodeStringBuilder.append("0");
    }
    unicodeStringBuilder.append(hexValue);
    }
    return unicodeStringBuilder.toString();
    }

输出:\\ u3132 \\ u3334 \\ u3536 \\ u3738 \\ u2841 \\ u7369 \\ u6373 \\ u2028 \\ uffffe282 \\ uffffa1e3 \\ uffff81b7 \\ uffffe283 \\ uffff82e3 \\ uffff81af \\ uffffe282 \\ uffffb8e3 \\ uffff82af \\ uffffe283 \\ uffffbbe3 \\ uffff81 \\ uffffbb33

但这也是错误的,因为我将两个单字节字符合并为一个。 我该如何克服呢?

我不知道您其他代码的特定要求。 但是我的建议是不要重蹈覆辙,而是使用API​​的内置编码功能。

例如,根据您需要的字节序调用带有StandardCharsets.UTF_16BEStandardCharsets.UTF_16LEgetBytes

String s = "1234567(Asics (アシックスワーキング) )";

byte[] utf8 = s.getBytes(StandardCharsets.UTF_8);
byte[] utf16 = s.getBytes(StandardCharsets.UTF_16BE); // high order byte first

System.out.println(s.length()); // 28
System.out.println(utf8.length); // 48
System.out.println(utf16.length); // 56 (2 bytes for each char)

正如他们在上面所述,java中string的内部表示是utf-16。 发现

对您的情况有用的Character.codePointAt()和Integer.toHexString()。

将参数重命名为theString,还从原始方法中删除了throws Exception子句,因为未引发任何异常。 (通常,将这些通用异常抛出是不好的做法)

public static String convertToEscaped(String theString) {
    char[] charArr = theString.toCharArray();

    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < charArr.length; i++) {
        String hexString = Integer.toHexString(Character.codePointAt(charArr, i));

        sb.append("\\u");

        if (hexString.length() == 2) {
            sb.append("00");
        }
        sb.append(hexString);
    }
    return sb.toString();
 }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM