将以单个空字节结尾的字节数组转换为UTF16编码的字符串

时间:2017-11-07 12:44:13

标签: java string utf-16

我得到一个字节数组,其中包含用UCS-2LE编码的字符串,通常,UCS-2LE字符串中的空字符串终结符将被编码为两个空字节(00 00),但有时只有一个字符串为下面:

import java.nio.charset.Charset;
import java.util.Arrays;

class Ucs {
    public static void main(String[] args) {
        byte[] b = new byte[] {87, 0, 105, 0, 110, 0, 0}; 
        String s = new String(b, Charset.forName("UTF-16LE"));
        System.out.println(Arrays.toString(s.getBytes()));
        System.out.println(s);
    }   
}

此程序输出

  

[87,105,110,-17,-65,-67]
  赢

我不知道为什么字符串的内部字节数组增长以及未知的unicode来自何处。我怎样才能消除它?

2 个答案:

答案 0 :(得分:1)

使用InputStreamReader以及正确的Charset或自定义CharsetDecoder

Reader reader = new InputStreamReader(
   new ByteArrayInputStream(new byte[]{87, 105, 110, -17, -65, -67,0,0}),
   Chaset.forName("UTF-16LE"));

Reader reader = new InputStreamReader(
   new ByteArrayInputStream(new byte[]{87, 105, 110, -17, -65, -67,0,0}),
   new CharsetDecoder(Chaset.forName("UTF-16LE"),1,2){
      @Override
      protected CoderResult     decodeLoop(ByteBuffer in, CharBuffer out){
        // detect trailing zero(s) to skip them
        // maybe employ the first version to do actual conversion
      }
   });

答案 1 :(得分:1)

黑客会忽略最后的奇数字节帮助吗?

int bytesToUse = b.length%2 == 0 ? b.length : b.length - 1;
String s = new String(b, 0, bytesToUse, Charset.forName("UTF-16LE"));