*介绍nio的字符处理功能,实现将buffer的内容装换为各种字符编码格式. *示例,演示了如何使用Charset编码和解码 java.nio.charset.Charset示例/** * Feb 2...
*介绍nio的字符处理功能,实现将buffer的内容装换为各种字符编码格式.
*示例,演示了如何使用Charset编码和解码
java.nio.charset.Charset示例/**
* Feb 25, 2011 by dzh
*/
package nio.charset;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CharsetEncoder;
import java.nio.charset.CoderResult;
import java.util.Iterator;
/**
* @author dzh
*
*/
public class CharsetTest {
public static void main(String[] args) throws Exception {
System.out.println("*******************************************");
if(Charset.isSupported("gbk"))
System.out.println("GBK is supported");
System.out.println("The default charset of this java jvm is "+Charset.defaultCharset().displayName());
System.out.println("*******************************************");
Iterator<String> iter =Charset.availableCharsets().keySet().iterator();
while(iter.hasNext())
System.out.println(iter.next());
System.out.println("*******************************************");
Charset charset =Charset.forName("gbk");
CharBuffer inBuf0 =CharBuffer.wrap("光福香雪海,踏春寻梅.");
CharBuffer inBuf1 =CharBuffer.wrap("湖光山色,洞天福地");
ByteBuffer outBuf =ByteBuffer.allocate(1000);
//encoder inBuf0
CharsetEncoder encoder =charset.newEncoder();
CoderResult coderResult =encoder.encode(inBuf0, outBuf, false);//false设置encoder的状态为未完成
if(isInvalid(coderResult)){
System.out.println(coderResult.toString());
return;
}
//encode inBuf1
coderResult =encoder.encode(inBuf1, outBuf, true); //true告知encoder,编码工作结束
if(isInvalid(coderResult)){
System.out.println(coderResult.toString());
return;
}
encoder.flush(outBuf); //设置编码器的完成状态等
outBuf.flip();
//decoder
CharsetDecoder decoder =charset.newDecoder();
CharBuffer restoredBuf =decoder.decode(outBuf);
System.out.println(restoredBuf.toString()); //输出解码后的字符串
}
/**
* 判断不合法状态
* @param coderResult
* @return
*/
public static boolean isInvalid(CoderResult coderResult){
if(coderResult.isError()||coderResult==CoderResult.OVERFLOW)
return true;
return false;
}
}
---CharsetEncoder和CharsetDecoder都有2种操作形式,
以encoder为例,[1]CharsetEncoder.encode(CharBuffer in, ByteBuffer out, boolean endOfInput)和[2]CharsetEncoder.encode(CharBuffer in)
从源码可见,[1]有可以复用out,[2]则每次产生新的out buffer.上面的示例使用的是[1]方式,多次编码时,更加有效率,但是注意要调用flush().
*CharsetEncoder
---编码器有4个内部状态,表示它的工作状态.
调用一些方法会改变这些状态,同时一些方法的执行是需要特定的状态的,如flush()需要state == ST_END.
---CharsetEncoder.reset(),当重新使用encoder时调用它,"clearing any charset-specific internal state",state = ST_RESET.
*CoderResult
---记录编码和解码的结果状态,有5个状态
private static final int CR_UNDERFLOW = 0;
private static final int CR_OVERFLOW = 1;
private static final int CR_ERROR_MIN = 2;
private static final int CR_MALFORMED = 2;
private static final int CR_UNMAPPABLE = 3;
---CoderResult.UNDERFLOW
either the input buffer has been completely consumed or, if the input buffer is not yet empty,that additional input is required.
---CoderResult.OVERFLOW
there is insufficient room in the output buffer,这个情况也属于错误,但isError()不检测这样情况
---isError
public boolean isError() {
return (type >= CR_ERROR_MIN);
}
*总结
---通过示例说明了nio如何处理字节编码的一般方式.
---内部状态的设计风格,值得学习.