先啰嗦一点废话,之前代码遇到错误,第一时间去百度,这次选择了阅读源码。然后真的是茅塞顿开,理解的更加深刻透彻,也节约了时间。然后考虑到源码都是英文的,可能阅读有困难,这时候就要推荐一个插件了==> Translation
背景
是在了解NIO的字符集Charset时遇到的问题。代码如下:
@Test
public void CharacterEncodingTest() throws CharacterCodingException {
Charset charset = Charset.forName("UTF-8");
Charset charset1 = Charset.forName("GBK");
// 获取编码器 utf-8
CharsetEncoder encoder = charset.newEncoder();
// 获得解码器 gbk
CharsetDecoder decoder = charset1.newDecoder();
CharBuffer buffer = CharBuffer.allocate(1024);
buffer.put("绝不敷衍,从不懈怠!");
buffer.flip();
// 编码
ByteBuffer byteBuffer = encoder.encode(buffer);
for (int i = 0; i < buffer.limit()*2; i++) {
System.out.println(byteBuffer.get());
}
// 解码
byteBuffer.flip();
CharBuffer charBuffer = decoder.decode(byteBuffer);
System.out.println(charBuffer.toString());
}
在for循环中使用过到了ByteBuffer的get()方法。一开始习惯性的在get()方法里加上了变量i随即出现了问题,无法取得数据。注释代码byteBuffer.flip();
之后可以执行。当直接使用get()方法时,不加byteBuffer.flip();
则会报错。所以就来区别一下ByteBuffer里的get();与get(int index);的区别。
探索
查看get();方法源码
/**
* Relative <i>get</i> method. Reads the byte at this buffer's
* current position, and then increments the position.
* @return The byte at the buffer's current position
*
* @throws BufferUnderflowException
* If the buffer's current position is not smaller than its limit
*/
public abstract byte get();
可以看出返回的值是“ The byte at the buffer’s current position”,就是返回缓冲区当前位置的字节。"then increments the position"也说明了返回字节之后,position会自动加1,也就是指向下一字节。
查看get(int index);方法源码
/**
* Absolute <i>get</i> method. Reads the byte at the given
* index.
* @param index
* The index from which the byte will be read
*
* @return The byte at the given index
*
* @throws IndexOutOfBoundsException
* If <tt>index</tt> is negative
* or not smaller than the buffer's limit
*/
public abstract byte get(int index);
由“The byte at the given index”可以知道返回的是给定索引处的字节。position并未移动。如果之后再执行flip();操作则读取不到任何数据,原因见下。
查看flip();方法源码
public final Buffer flip() {
limit = position;
position = 0;
mark = -1;
return this;
}
注意:limit=position
,如果使用get(int index);的方法,则执行完position = 0,所以limit也会变成0,之后无法读取数据。
最后
关于NIO完整的笔记待参考我的下一篇笔记:学习NIO