前几天被问到nio的知识,之前没有特别留心这些,竟然回答的一塌糊涂,哎,以后看到的东西应该仔细想想,不能蜻蜓点水一样就过了。
nio里面的知识,大概看了一下,说多也不多。包括其中的buffer,之前通信时候,经常用到的,但是和它相关的其他东西并没怎么看,一定要多留心。
-------------------------------
buffer里面,很常用的应该是flip()这个方法,这个方法是将buffer从写的模式,变成读的模式。我也画了一个简单的图来演示一下这个含义。
先说写模式:创建buffer的时候,allocate(size) 一个我们的buffer(什么bytebuffer,charbuffer。。。),这个里面还是个空的。初始的时候position在第一个位置,limit是buffer的容量,每当我们写入数据的时候,position就开始往前走,直到把这个buffer写满(如果数据量小于容量,那就写不满)。如果最终写完,那么positon和limit一样,也就是buffer容量大小。
要变成读的模式,就要从头开始读取数据。flip()方法,是将该buffer的position重置为0,把limit重置为之前position的位置。这样,读的时候:
while (buffer.position() <buffer.limit()){
//get data
buffer.get();
}
还有其他几个比较常用的方法:
clear()和compact(),前者是将buffer清空,将position重置为0,limit重置到末尾。这样,buffer又相当于是一个新的buffer了;后者是将未读取的数据放到buffer的前面,position重置到该段未读数据的后面,limit还是到末尾。
mark()和reset(),前者是在position处mark一下,后者是返回到该mark的position。
equals() 和compareTo():
当满足下列条件时,表示两个Buffer相等:
- 有相同的类型(byte、char、int等)。
- Buffer中剩余的byte、char等的个数相等。
- Buffer中所有剩余的byte、char等都相同。
如果满足下列条件,则认为一个Buffer“小于”另一个Buffer:
- 第一个不相等的元素小于另一个Buffer中对应的元素 。
- 所有元素都相等,但第一个Buffer比另一个先耗尽(第一个Buffer的元素个数比另一个少)
@Test public void readFile(){ try { RandomAccessFile file = new RandomAccessFile("/home/wang/1D","rw"); FileChannel channel = file.getChannel(); ByteBuffer buffer =ByteBuffer.allocate(1024); try { int bytesRead = channel.read(buffer); System.out.println("data buffer length:"+bytesRead); while (bytesRead != -1){ buffer.flip(); buffer.hasRemaining(); while (buffer.position() <buffer.limit()){ System.out.print((char) buffer.get()); } System.out.println("begin clear buffer for read continue"); buffer.clear(); bytesRead = channel.read(buffer); } } catch (IOException e) { e.printStackTrace(); } try { System.out.println("begin close file"); file.close(); } catch (IOException e) { e.printStackTrace(); } } catch (FileNotFoundException e) { e.printStackTrace(); } }
参考资料:
http://ifeve.com/buffers/