Buffer:
Buffer的三个重要属性:capacity, limit, position; position的值永远都不可能大于limit的值。
先定义一个容量为6的buffer,位置如图所示
如果先读入4个数据,读入完成后position的索引是4;再进行写操作,需要经过Flip:将position指向第一个进行写的位置,即0位置,limit指向原来的position位置,即4位置。当position的值与limit的值相等时就是不可以再写了。Capacity的值一直保持不变。4个数据都读完后,再调用flip方法,则position指向0位置,limit位置不变。
public final Buffer flip() {
limit = position;
position = 0;
mark = -1;
return this;
}
NIO内存的分配主要有两种,一种是堆上的内存分配,一种是堆外的内存分配。堆外的内存不是有JVM控制的,是由操作系统统一处理的。DirectBuffer:零拷贝。
文件通道:
通过NIO读取文件涉及到3个步骤:
- 从FileInputStream获取到FileChannel对象。
- 创建Buffer
- 将数据从Channel读取到Buffer中
绝对方法与相对方法的含义:
- 相对方法:limit值和position值会在操作时被考虑到
- 绝对方法:完全忽略掉limit与position值。通过索引直接get或put相应的值。
@Test
public void TestFileNio() throws Exception {
FileInputStream fileInputStream = new FileInputStream("input.txt");
FileOutputStream fileOutputStream = new FileOutputStream("output.txt");
FileChannel inChannel = fileInputStream.getChannel();
FileChannel outChannel = fileOutputStream.getChannel();
// ByteBuffer buffer = ByteBuffer.allocate(1024);
ByteBuffer buffer = ByteBuffer.allocate(3);//当buffer只分配4个字节,重复多次用
while (true){
buffer.clear();//如果注释掉这一行,则内容会不停的循环输出;
//因为position没有置为0,buffer中数据不会更新。且buffer中position位置为limit位置,
// 使用下面的read时不会有字节被读取,read一直返回0,不会结束循环
System.out.println("before read position:" + buffer.position());
int read = inChannel.read(buffer);//从channel中读取数据到buffer,如果channel数据读完,返回值为-1
System.out.println("after read position:" + buffer.position());