一、出错原因
例子摆出:
String raw = "长坂桥头杀气生,横枪立马眼圆睁。一声好似轰雷震,独退曹家百万兵。";
Charset charset = StandardCharsets.UTF_8;
byte[] bytes = charset.encode(raw).array();
byte[] bytes2 = Arrays.copyOfRange(bytes, 0, 11);
ByteBuffer bbuf = ByteBuffer.allocate(12);
CharBuffer cbuf = CharBuffer.allocate(12);
bbuf.put(bytes2);
//将Position移动到最前面,开始读取
bbuf.flip();
System.out.println(charset.newDecoder().decode(bbuf));
这样运行代码会报错:java.nio.charset.MalformedInputException: Input length = 2
这个的意思说有2个不能识别的。
因为我们UTF-8,一个中文等于三个字节,中文标点占三个字节。 一个英文字符等于一个字节,英文标点占一个字节。
我们这边只截取到半个中文因此报错。
二、解决方法
利用一个CharBuffer,再去编码的时候传入该CharBuffer
public void test_chinese() throws CharacterCodingException {
String raw = "长坂桥头杀气生,横枪立马眼圆睁。一声好似轰雷震,独退曹家百万兵。";
Charset charset = StandardCharsets.UTF_8;
byte[] bytes = charset.encode(raw).array();
byte[] bytes2 = Arrays.copyOfRange(bytes, 0, 11);
ByteBuffer bbuf = ByteBuffer.allocate(13);
CharBuffer cbuf = CharBuffer.allocate(13);
bbuf.put(bytes2);
//将Position移动到最前面,开始读取
bbuf.flip();
charset.newDecoder().decode(bbuf, cbuf ,true);
cbuf.flip();
char[] temp = new char[cbuf.length()] ;
if(cbuf.hasRemaining()){
cbuf.get(temp);
System.out.println("here:" + new String(temp));
}
System.out.format("limit-pos-%d\n", bbuf.limit() - bbuf.position());
Arrays.copyOfRange(bbuf.array(), bbuf.position(), bbuf.limit());
}
结果:
here:长坂桥
limit-pos-2
三、总结
我们可以借用CharBuffer将有效的中文字符截取出来,通过position与Limit查看多出的无效编码,方便将其取出放入另外部分,形成完整的中文。