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而登上历史舞台的。