志宇-NIO之Buffer

Buffer

Buffer是什么
它用来传输数据,应用于操作系统,是面向缓冲区的,非阻塞;
Buffer 缓冲区实际上就是一个数组, 把数组的内容与信息包装成一个 Buffer 对象,提供访问这些信息的方法;
Buffer常识
Buffer中有ByteBuffer,CharBuffer,DoubleBuffer,FloatBuffer, IntBuffer,LongBuffer,ShortBuffer,实际上使用较多的是 ByteBufer, CharBuffer;
在这里插入图片描述
Buffer用capacity、position、limit、mark属性用来对缓冲区读取信息进行标识;
capacity:创建Buffer时,缓冲区能存储多少数据,创建后不能修改可以清空继续写数据;
position:初始化为0,最大值为capacity-1,切换到读模式position会初始化为0;
limit:是指第一个不能被读出或写入的位置;
mark:设置的标记位置,使用mark方法对当前位置进行标记,使用reset方法将位置放到标志位置;
0 <= mark <= position <= limit <= capacity
在这里插入图片描述
切记切换成读模式后原来的positon会变成读模式的limit
直接字节缓冲区:缓冲区中只有ByteBuffer能够参与IO操作,直接字节缓冲区通常是 I/O 操作最好的选择,如果使用非直接字节缓冲区可能会导致性能损耗;
Buffer常用API
CharBuffer.allocate(int) 声明非直接缓冲区参数代表缓冲区大小
capacity() 方法返回缓冲区的大小
hasRemaining() 判断当前 position 后面是否还有可处理的数据,即判断postion与limit之间是否还有数据可处理
limt() 返回 limit 上限的位置
mark() 设置缓冲区的标志位置, 这个值只能在 0~position 之间。 以后可以通过 reset()返回到这个位置
position() 可以返回 position 当前位置
remainig() 返回当前 position 位置与 limit 之间的数据量
reset() 方法可以将 position 设置为 mark 标志位
rewind() 将 position 设置为 0, 取消 mark 标志位
clear() 清空缓冲区,仅仅是修改 position 标志为 0, 设置 limit 为 capacity, 缓冲区中数据还是存在的
flip() 方法可以把缓冲区由写模式切换到读模式。 先把 limit 设置为 position 位置,再把position 设置为 0
compact() 把 buffer 中未读的数据复制到 position 为 0 的位置
ByteBuffer.allocateDirect();方法创建直接字节缓冲区
简单使用
使用CharBuffer进行简单读写

package com.lizhiyu.com;

import java.nio.CharBuffer;

public class Test {
	public static void main(String[] args) {
    	//创建缓冲区
    	CharBuffer buffer=CharBuffer.allocate(100);
    	buffer.put('1');
    	buffer.put('2');
    	buffer.put('3');
    	buffer.put('4');
    	buffer.put('5');
    	System.out.println(
    			"capacity:" + buffer.capacity() +
    			",limit:" + buffer.limit() + 
    			",position:" + buffer.position());
    	//切换成读模式,position设置成0,数据不变
    	buffer.flip();
    	//通过循环把 position 与 limit 之间的内容逐个打印
    	while(buffer.hasRemaining()){
    		//获得数据后position+1
    		System.out.println(buffer.get());
    	}
    	//仅仅是清空limit和position的值,不对数据进行清空
    	buffer.clear();
    	System.out.println(
    			"capacity:" + buffer.capacity() +
    			",limit:" + buffer.limit() + 
    			",position:" + buffer.position());
    	//当切换为读模式的时候position 的位置变为limit为存储数据的数量
    	//之前调用了clear方法,limit为之前的position位置
    	//之前调用了clear方法limit变成了capacity所以打印除了所有数据
    	System.out.println(buffer);
    	while(buffer.hasRemaining()){
    		//获得数据后position+1
    		System.out.println(buffer.get());
    	}
    }
}

使用数组进行创建CharBuffer,批量读取CharBuffer

package com.lizhiyu.com;

import java.nio.CharBuffer;

public class Test {

	public static void main(String[] args) {
		char[] charArray={'1','2','3','4','5','6','7','8','9','a'};
		//通过CharBuffer.wrap方法将charArray中的数据创建一个缓冲区
		 CharBuffer charBuffer = CharBuffer.wrap(charArray);
		 charBuffer.get();
		 
		 char[] charArray2=new char[10];
		 //将缓冲区的数据从position开始到limit 放到charArray2数组中
		 //charBuffer.remaining()代表position和limit中相差多少
		 CharBuffer charBuffer2 = charBuffer.get(charArray2, 0, charBuffer.remaining());
		 charBuffer2.flip();
		 System.out.println(charBuffer2);
		 
		 //将数据批量写入缓冲区
		 CharBuffer charBuffer3=CharBuffer.allocate(10);
		 charBuffer3.put(charArray,0,charBuffer3.remaining());
		 charBuffer3.flip();
		 System.out.println(charBuffer3);
	}
}

缓冲区的复制与分隔,CharBuffer随着其绑定数组改变而改变

package com.lizhiyu.com;

import java.nio.CharBuffer;

public class Test {
	public static void main(String[] args) {
		//通过put往缓冲区中批量添加数据
		CharBuffer charBuffer=CharBuffer.allocate(16);
		charBuffer.put("1234567890");
		charBuffer.flip();
		System.out.println(charBuffer);
		
		char[] charArray= {'1','2','3','4','5'};
		//通过数组创建缓冲区,数组中的数据改变缓冲区中的数据跟着改变
		CharBuffer charBuffer2 = CharBuffer.wrap(charArray);
		System.out.println(charBuffer2);
		charBuffer2.get();
		//缓冲区的复制
		//使用duplicate进行复制出来的buffer底层引用同一个数组
		//将position也会进行复制
		CharBuffer duplicate = charBuffer2.duplicate();
		System.out.println(duplicate);
		
		//设置位置
		duplicate.position(3);
		//将缓冲区进行分割
		//创建一个新的缓冲区数据为原来缓冲区的[position,limit)
		CharBuffer sliceBuffer = duplicate.slice();
		System.out.println(sliceBuffer);
	}
}

缓冲区IO操作
使用ByteBuffer联合Channel进行读取文件
其中使用直接字节流缓冲区性能更高,读取文件速度可能会更快

//非直接字节流缓冲区
ByteBuffer byteBuffer=ByteBuffer.allocate(100);
//直接字节流缓冲区
ByteBuffer allocateDirect = ByteBuffer.allocateDirect(100);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值