【NIO总结】—NIO中的缓冲区
来源:互联网 发布:旅行商问题算法 编辑:程序博客网 时间:2024/06/06 11:43
NIO中的缓冲区是一个用于特定基本数据类型的容器。在java.io包中定义,所有缓冲区都是Buffer抽象类的子类。Buffer主要用于和NIO通道进行交互,数据可以从通道读入缓冲区,也可以从缓冲区写入到通道中。Buffer就像一个数组,可以保存多个相同类型的数据。
缓冲区的类型
根据数据类型的不同,缓冲区的类型分为以下几类,其中不包括boolean对应的Buffer:
ByteBuffer:字节缓冲区
CharBuffer:字符缓冲区
DoubleBuffer:双精浮点缓冲区
FloatBuffer:单精浮点缓冲区
IntBuffer:整型缓冲区
LongBuffer:长整型缓冲区
ShortBuffer:短整型缓冲区
这些不同的Buffer类都采用相似的方法操作数据,只不过操作的数据类型不同而已。例如:
获取缓冲区(以字节缓冲区为例):ByteBuffer buffer = ByteBuffer.allocate(int capacity)或ByteBuffer buffer = ByteBuffer.allocateDirect(int capacity)。
存入数据(以字节缓冲区为例):buffer.put("a".getBytes()),提供单个字节存入或以字节数组的形式存入。
取出数据(以字节缓冲区为例):buffer.get(),提供获取单个字节的操作,也提供取出字节数组的形式。
清空缓冲区(以字节缓冲区为例):buffer.clear(),清空缓冲区并返回对缓冲区的引用,清空后数据不会丢失,只不过被标记为“被遗忘”状态,通过get还是可以获取到。
设置可读状态(以字节缓冲区为例):buffer.flip(),将缓冲区的界限设置为当前位置,并将当前位置设置为0,使得buffer设置为可读状态,此时可将buffer中的数据写入到channel中。
重复可读(以字节缓冲区为例):buffer.rewind(),将buffer设置为重复可读,也就是将当前位置设置为0,并取消设置的mark。
核心概念
容量(capacity):表示Buffer的最大容量,缓冲区容量不能为负,并且创建后不可更改。
限制(limit):第一个不能读取或写入的数据的位置,即位于limit后面的数据不可读写。缓冲区的限制不能为负,也不能大于容量。
位置(position):下一个要读取或写入的数据的索引。缓冲区的位置不能为负,并且不能大于其限制。
标记(mark)与重置(reset):标记是一个索引,通过Buffer中的mark()方法制定一个特定的position,之后可以调用reset()方法将position恢复到当前mark所在的位置。
它们四个索引的值关系为:0 <= mark <= position <= limit <= capacity。
当Buffer创建时,设置容量为10,此时的capacity=10,limit=10,position=0,当向Buffer中存入数据后,对于字节缓冲区来说,每存入一个字节,position就会向后移动1,如果存入5个字节,此时position的位置便是5,因为索引下标是从0开始的。当buffer调用flip()方法切换到读模式后,会将limit置为position,将position置为0,此时就可以从buffer中读取数据。随着数据不断读取,position不断后移,直至移动到limit的位置,表示数据读取完全。如果读取数据时要求不从第0个位置开始读,而是从第2个位置开始,此时就要调用mark()方法将position标记到第2个位置,这样再次读取的时候就会从mark标记的位置开始读,调用reset()方法可将position设置到mark的位置。rewind()方法可以设置重复读,一次读取完成后,调用rewind()方法,将position置为0,再次开始读取,类似于flip()。下面的方法可以测试上面的核心概念以及常用的Buffer的方法:
@Testpublic void testCoreConception(){ //1、创建一个Buffer ByteBuffer buffer = ByteBuffer.allocate(10); System.out.println(buffer.position()); System.out.println(buffer.limit()); System.out.println(buffer.capacity()); //2、向Buffer中加入5个字符 buffer.put("a".getBytes()); buffer.put("b".getBytes()); buffer.put("c".getBytes()); buffer.put("d".getBytes()); buffer.put("e".getBytes()); System.out.println("\n"); System.out.println(buffer.position()); System.out.println(buffer.limit()); System.out.println(buffer.capacity()); //3、执行flip()方法后 buffer.flip(); System.out.println("\n"); System.out.println(buffer.position()); System.out.println(buffer.limit()); System.out.println(buffer.capacity()); //4、从Buffer中get数据之后 byte data = buffer.get(); System.out.println("\n"); System.out.println(buffer.position()); System.out.println(buffer.limit()); System.out.println(buffer.capacity()); //5、测试rewind() buffer.rewind(); System.out.println("\n"); System.out.println(buffer.position()); System.out.println(buffer.limit()); System.out.println(buffer.capacity()); //6、测试mark()和reset() byte data0 = buffer.get(); buffer.mark(); byte data1 = buffer.get(); buffer.reset(); System.out.println("\n"); System.out.println(buffer.position()); System.out.println(buffer.limit()); System.out.println(buffer.capacity()); //7、测试clear() buffer.clear(); System.out.println("\n"); System.out.println(buffer.position()); System.out.println(buffer.limit()); System.out.println(buffer.capacity()); byte data2 = buffer.get(); System.out.println((char)data2);}
直接和非直接缓冲区
缓冲区的创建方式有两种,allocate(int capacity)和allocationDirect(int capacity),两种方式都是创建缓冲区,前面的一种是创建非直接缓冲区,后面的方法是创建直接缓冲区。
非直接缓冲区:非直接缓冲区是由allocate()方法创建的,创建后存在于JVM内存中。此时在内核地址空间和用户地址空间之间存在着数据copy的过程,降低了数据传输的效率。
直接缓冲区:直接缓冲区是由allocateDirect(int capacity)方法创建的,也可以通过FileChannel的map()方法将文件区域直接映射到内存中来创建。直接缓冲区是占用物理内存的,在物理内存中创建映射文件,从而取消了内核地址空间和用户地址空间之间的数据copy过程,提高了效率。
直接缓冲区和非直接缓冲区可以通过isDirect()方法来判断,非直接缓冲区占用JVM内存,缓冲区的分配和取消都是建立在JVM的基础上的,不会影响物理内存。直接缓冲区将映射文件映射在屋里内存中,它的分配和取消通常需要更高的成本,如果数据量较大,可能会占用内存过多导致电脑卡顿。所以,如果需要频繁创建或取消的缓冲区,最好使用非直接缓冲区,而相对稳定的缓冲区可以使用直接缓冲区。
@Testpublic void testDirectBuffer(){ ByteBuffer buffer = ByteBuffer.allocate(10); ByteBuffer buffer1 = ByteBuffer.allocateDirect(10); System.out.println(buffer.isDirect()); System.out.println(buffer1.isDirect());}
- 【NIO总结】—NIO中的缓冲区
- NIO中的缓冲区
- NIO中的缓冲区
- Java NIO中的缓冲区
- 【NIO总结】—NIO中的通道
- 【NIO总结】—NIO简介
- NIO —— 缓冲区Buffer
- java NIO —— 缓冲区
- JAVA NIO总结(二)—缓冲区原理
- java NIO(九) 缓冲区——字节缓冲区&&直接缓冲区
- Java NIO中的缓冲区Buffer(二)创建-复制缓冲区
- Java NIO中的缓冲区Buffer(二)创建-复制缓冲区
- Java NIO中的缓冲区Buffer(二)创建-复制缓冲区
- Java NIO中的缓冲区Buffer(二)创建-复制缓冲区
- Java NIO——2 缓冲区
- Java NIO —— Buffer(缓冲区)
- java nio 缓冲区学习
- NIO - Buffer缓冲区
- 百练_2701:与7无关的数
- [译]精通 Android 中的 tools 命名空间
- Java实现MD5加密_字符串加密_文件加密
- IOS UITextView内容垂直居中方法
- Hadoop之HBase框架学习基础实践篇(笔记16)
- 【NIO总结】—NIO中的缓冲区
- SpringBoot注解说明
- 机器学习之决策树预测——泰坦尼克号乘客数据实例
- IP制作流竟然离我如此之近
- spring+mybatis通过ApplicationContext实现Autowired
- 《剑指offer》求1+2+3+...n(不用if、else、乘除等)
- spark--transform算子--sortByKey
- 安卓 MediaCodec解码aac
- 设置UITextView的行间距