java NIO Exception in thread "main" java.nio.charset.MalformedInputException: Input length = 1

package com.nio;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;

public class TestNIOByteBuffer {
    public static void main(String[] args) throws IOException{

        //测试charset
        File file = new File("D:\\aa.txt");
        FileInputStream fin = new FileInputStream(file);
        FileChannel fc = fin.getChannel();  
        Charset charset = Charset.forName("UTF-8");
        ByteBuffer buffer = ByteBuffer.allocate((int) file.length());
        while((fc.read(buffer))>0){
            buffer.flip();
            CharsetDecoder decoder = charset.newDecoder();
            CharBuffer charbuffer = decoder.decode(buffer);
            System.out.println(charbuffer);
            buffer.clear();
        }
        fc.close;
        
    }
}

报错信息:

Exception in thread "main" java.nio.charset.MalformedInputException: Input length = 1
    at java.nio.charset.CoderResult.throwException(CoderResult.java:281)
    at java.nio.charset.CharsetDecoder.decode(CharsetDecoder.java:816)
    at com.nio.TestNIOByteBuffer.main(TestNIOByteBuffer.java:42)



代码看起来自以为没问题,但是为啥会报错呢?

仔细一分析,你就会发现:

获得的ByteBuffer 是不可以随意的对其进行decode,那为什么不可以对一个ByteBuffer进行字符的解码呢?原因很简单其实是:java中一个汉字是由2个字节组成,但是我们不能保证这个buffer里面都可以成功解码成汉字。其中也许有“半个汉字”也说不准。所以当有半个汉字的时候就会出现这个异常。decoder 解析不了 半个汉字所以它迷茫了。就抛出个一场来。

通常的解决思路是:每次都去判断一下:Bytebuffer中最后一个字节是否合法;如果不合法,则说明这个字节是双字节汉字的一部分,这样我们解码时就不要包含这个字节,而是把这个字节放进下次解码之前的Bytebuffer中。这样做,系统就不会抛出“无法正确解码”这类的异常了。

 

现在来看,NIO真的适合用来显示文件内容?答案是:不适合。其实NIO主要是使用在socket网络编程领域,它的出现也仅仅为了弥补IO在网络编程中的缺憾。不错,NIO并不是为了取代IO而登上历史舞台的。

你可能感兴趣的:(java NIO Exception in thread "main" java.nio.charset.MalformedInputException: Input length = 1)