Java NIO中的缓存区(Buffer)用于和通道(Channel)进行交互。数据是从通道读入缓冲区,从缓冲区写入到通道中的。java
缓冲区本质上是一块能够写入数据,而后能够从中读取数据的内存。这块内存被包装成NIO Buffer对象,并提供了一组方法,用来方便的访问该块内存。数组
Buffer底层使用数组实现。缓存
Java NIO中,根据数据类型不一样(boolean 除外),提供了相应类型的缓冲区:app
使用Buffer读写数据通常遵循如下四个步骤:this
写入数据到Buffer;code
调用flip()
方法;对象
从Buffer中读取数据;blog
调用clear()
方法或者compact()
方法;ip
当向buffer写入数据时,buffer会记录下写了多少数据。一旦要读取数据,须要经过flip()方法将Buffer从写模式切换到读模式。在读模式下,能够读取以前写入到buffer的全部数据。内存
一旦读完了全部的数据,就须要清空缓冲区,让它能够再次被写入。有两种方式能清空缓冲区:调用clear()或compact()方法。clear()方法会清空整个缓冲区。compact()方法只会清除已经读过的数据。任何未读的数据都被移到缓冲区的起始处,新写入的数据将放到缓冲区未读数据的后面。
String str = "charBuffer"; CharBuffer charBuffer = CharBuffer.allocate(1024); charBuffer.put(str); charBuffer.append("--"); charBuffer.append("hello world"); charBuffer.flip(); //单个读取buffer中的内容 /*while (charBuffer.hasRemaining()) { System.out.println(charBuffer.get()); }*/ //一次性读取buffer中的内容 char[] dst = new char[charBuffer.limit()]; charBuffer.get(dst); System.out.println(new String(dst));
public abstract class Buffer { // Invariants: mark <= position <= limit <= capacity private int mark = -1;//标记位置 private int position = 0;//当前游标位置 private int limit;//可读取数据大小 private int capacity;//buffer容量大小 ... }
标记当前位置,配合reset使用。
public final Buffer mark() { mark = position; return this; }
重置游标为标记位。
public final Buffer reset() { int m = mark; if (m < 0) throw new InvalidMarkException(); position = m; return this; }
清除缓冲区,等待写入。
public final Buffer clear() { position = 0; limit = capacity; mark = -1; return this; }
将缓冲区由写模式切换为读模式。
public final Buffer flip() { limit = position; position = 0; mark = -1; return this; }
重置buffer,等待写入。
public final Buffer rewind() { position = 0; mark = -1; return this; }
获取剩余可读元素个数。
public final int remaining() { return limit - position; }
判断是否还有可读元素。
public final boolean hasRemaining() { return position < limit; }