Java NIO Buffer 实践与概念

通过JAVA NIO Buffer 进行读写一般需要下面的4步骤:

1、写入数据到Buffer

2、调用buffer.flip()

3、从Buffer中读取数据

4、调用buffer.clear()或者buffer.compact()方法

下面我们看一个例子:

public class BuffterClient {
public static void main(String[] args) throws IOException {
RandomAccessFile aFile = new RandomAccessFile("data.txt", "rw");
FileChannel inChannel = aFile.getChannel();
ByteBuffer buf = ByteBuffer.allocate(48);
int bytesRead = inChannel.read(buf); //从Buffer中读
while (bytesRead != -1) {
buf.flip(); //将写模式变成读模式,pos被重置为0
while (buf.hasRemaining()) {
System.out.print((char) buf.get()); //buf.get()读取数据
}
buf.clear(); //清空Buffer,pos=0,limit=cap
bytesRead = inChannel.read(buf);
}
aFile.close();
}
}

输出结果:

show me the money1
show me the money2
show me the money3
show me the money4
show me the money5
show me the money6
Process finished with exit code 0

Buffer:

我们可理解成一个内存块,内存块需要设置容量,通过Channel开个这个内存块,内存可以读写,顺理成章Buffer也支持读取数据获取写入数据到Buffer。

Buffer 三个属性:

capacity,position,limit ,下面我们看这三个属性,方便我们理解Buffer的设计思路

Java NIO Buffer 实践与概念

Capacity:

1、设置内存的容量,可以将capacity bytes,longs 进入Buffer。如果Buffer 满了,在你写buffer的时候需要先清空buffer。

Position:

当你写数据到Buffer的时候,你需要知道position。初始position为0,每次插入数据position会加1

当你从Buffer读取数据的时候,也需要只是position的位置。flip将写模式转换到读模式,位置被重置为0。

Limit:

限制每次读取的最大数

Buffer 类型:

  • ByteBuffer
  • MappedByteBuffer
  • CharBuffer
  • DoubleBuffer
  • FloatBuffer
  • IntBuffer
  • LongBuffer
  • ShortBuffer

分配Buffer大小:

ByteBuffer buf = ByteBuffer.allocate(48);

写入Buffer的两种方式:

1、通过Channel 写入数据到Buffer

2、通过Buffer本身的put()方法写入数据

Flip()方法

将写模式转换到读模式,设置position为0,设置limit=position。

从Buffer中读取数据的方式:

1、通过Channel读取数据到Buffer

2、通过Buffer.get()方法

Rewind()方法:

设置position=0,可以进行反复的读取Buffer内容

clear()和compact():

buffer.clear()清空缓存,如果缓存有数据则会丢失 ,如果需要未阅读的数据后面在读, 可以使用compact()方法代替clear()方法 buffer.compact()方法会将未读取的数据放到Buffer的头(使用Unsafe.copyMemory()),最后设置pos为最后未读元素的最后,不会清空未读数据

mark()和reset():

通过buffer.mark()方法标记给定的Buffer的位置(pos),后面可以通过buffer.reset()方法将pos回到mark的pos
伪代码:
buffer.mark()
//call buffer.get()
buffer.reset(); // 设置pos为mark

equals()和compareTo():

equals():
同样的数据类型(byte,int etc) + 相同数量的字节数 + 所有剩余的字节数
compareTo():
在两个buffer进行比较剩余的元素
所有的元素相等,但是第一个缓存区的元素在第二个缓冲区之前耗尽了数据
与另一个缓冲区中的对应相等的第一个元素小于另一个缓冲区中的元素

代码地址:https://github.com/yuanzongyu/tutorials/tree/master/core-java-io/src/main/java/xin/clips/nio


分享到:


相關文章: