diff --git a/java se/nio.md b/java se/nio.md index c2c74c2..05baf24 100644 --- a/java se/nio.md +++ b/java se/nio.md @@ -69,6 +69,94 @@ buffer的mark操作标识对buffer执行reset操作后position会被重置到的 > > 如果想要对buffer中的数据进行重新读取,可以调用`rewind()`方法,其将position设置为0,从而可以对[0, limit-1]范围内的数据重新进行读取。 +#### Buffer get/put方法 +##### get +在ByteBuffer中,拥有如下`get`方法: +```java +byte get(); +ByteBuffer get( byte dst[] ); +ByteBuffer get( byte dst[], int offset, int length ); +byte get( int index ); +``` +其中,前3个get方法都是relative方法,其基于当前position和limit来获取数据。第4个get方法则是absolute方法,其不基于position和limit,而是基于index绝对偏移量来获取数据。 + +> absolute get方法调用不基于position和limit,也不会对position和limit造成影响。 + +##### put +ByteBuffer拥有如下`put`方法: +```java +ByteBuffer put( byte b ); +ByteBuffer put( byte src[] ); +ByteBuffer put( byte src[], int offset, int length ); +ByteBuffer put( ByteBuffer src ); +ByteBuffer put( int index, byte b ); +``` + +#### Buffer allocation and warpping +在创建buffer之前,必须对buffer进行分配, +```java +ByteBuffer buffer = ByteBuffer.allocate(1024); +``` +`Buffer.allocate`会创建一个指定大小的底层数组,并将数组封装到一个buffer对象中。 + +除了调用`allocate`之外,还可以将一个已经存在的数组分配给buffer: +```java +byte array[] = new byte[1024]; +ByteBuffer buffer = ByteBuffer.wrap(array); +``` +在调用`wrap`方法之后,会创建一个buffer对象,buffer对象对array进行的包装。此后,既可以通过array直接访问数组,也可以通过buffer访问数组。 + +#### Buffer slice +buffer slice会基于buffer对象创建一个sub buffer,新建的sub buffer会和原来的buffer共享部分的底层数组数据。 + +```java +ByteBuffer buffer = ByteBuffer.allocate(10); + +for (int i = 0; i < buffer.capacity(); ++i) { + buffer.put((byte) i); +} + +buffer.position(3); +buffer.limit(7); + +ByteBuffer slice = buffer.slice(); +``` +通过上述方法,可以创建一个包含原始buffer[3,6]范围内元素的sub buffer。但是,sub buffer和buffer共享[3,6]范围内的数据,实例如下所示: +```java +// 将[3,6]范围内的元素都 * 11 +for (int i = 0; i < slice.capacity(); ++i) { + byte b = slice.get(i); + b *= 11; + slice.put(i, b); +} + +// 重置original buffer的position和limit并读取数据 +buffer.position(0); +buffer.limit(buffer.capacity()); +while (buffer.remaining() > 0) { + System.out.println(buffer.get()); +} +``` +修改sub buffer中的元素内容后,访问original buffer中的内容,输出结果如下所示: +```shell +$ java SliceBuffer +0 +1 +2 +33 +44 +55 +66 +7 +8 +9 +``` +易得知在sub buffer修改内容后,内容修改对buffer也可见。 + + + + + ### Channel Channel为一个对象,可以从channel中读取数据或向channel写入数据。将传统io和nio相比较,channel类似于stream。