缓冲区(Buffer)
来源:互联网 发布:软件健壮性 软件可靠性 编辑:程序博客网 时间:2024/05/02 00:41
1、 概念介绍
缓冲区(Buffer)就是在内存中预留指定大小的存储空间用来对I/O的数据做临时存储,这部分预留的内存空间叫缓冲区。
使用缓冲区有两个好处:
1、减少实际物理读写次数
2、缓冲区在创建时就被分配内存,这块内存区域一直被重用,可以减少动态分配和回收内存的次数
一般在实际过程中,我们一般是先将文件读入内存,再从内存写入到别的地方,这样在输入输出过程中我们都可以用缓存来提升IO性能。
在java nio中,缓冲区的作用也是用来临时存储数据,可以理解为是I/O操作中数据的中转站。缓冲区直接为通道(channel)服务,写入数据到通道或从通道读取数据,这样利用缓冲区数据来传递就可以达到对数据高效处理的目的。在nio中主要有八种缓冲区类(其中MappedByteBuffer是专门用于内存映射的一种ByteBuffer):
ByteBuffer,CharBuffer,ShortBuffer,IntBuffer,LongBuffer,FloatBuffer,DoubleBuffer
2、Fields
所有缓冲区都有4个属性:capacity、limit、position、mark,并遵循mark<=position<=limit<=capacity,下表时对这4个属性的解释:
我写了这几个方法的测试方法,大家可以运行起来理解:
public static void main(String[] args) { System.out.println("---------test allocate ------------"); System.out.println("before allocate:"+Runtime.getRuntime().freeMemory()); //如果分配的内存过小,大小不会变化,要超过多少jvm才能感觉到? ByteBuffer buffer=ByteBuffer.allocate(102400); System.out.println("buffer = "+buffer); System.out.println("after allocate:"+Runtime.getRuntime().freeMemory()); //这部分直接用的系统内存,所以对jvm的内存没有影响 ByteBuffer directBuffer=ByteBuffer.allocateDirect(102400); System.out.println("directBuffer = "+directBuffer); System.out.println("after allocate:"+Runtime.getRuntime().freeMemory()); System.out.println("---------- test wrap ---------"); byte[]bytes=new byte[32]; buffer=ByteBuffer.wrap(bytes); System.out.println(buffer); buffer=ByteBuffer.wrap(bytes,10,10); System.out.println(buffer); }
3、另外一些常用的方法
也即将未读的内容拷贝到缓冲区开头,现在buffer准备好写数据,但是不会覆盖未读的数据;
如果先将position设置到limit,再compact,那么相当于clear get() 相对读,从position读取一个byte,并将position+1,为下次读写做准备 get(int index) 绝对读,读取byteBuffer底层bytes下标为index的byte,不改变position get(byte[]dst,int offset,int length) 从position开始相对读,读length个byte,并写入dst下标从offset到offset+length的区域 put(byte b) 相对写,向position写入一个byte,并将position+1,为下次读写做准备 put(int index,byte b) 绝对写,想byteBuffer底层的bytes中下标为index的位置插入byte b,不改变position put(ByteBuffer src) 用相对写,把src中可读的部分(position-limit)写入到此byteBuffer) put(byte[]src,int offset,int length 将src数组中offset到offset+length的数据写入到position之后,并将position+length
以下是这些方法的测试代码:
public static void main(String[] args) { byte[]bytes=new byte[32]; ByteBuffer buffer=ByteBuffer.wrap(bytes); System.out.println(buffer); buffer=ByteBuffer.wrap(bytes,10,10); System.out.println("----------Test reset -----------"); buffer.clear(); buffer.position(5); buffer.mark(); buffer.position(10); System.out.println("before reset:"+buffer); buffer.reset(); System.out.println("after reset:"+buffer); System.out.println("----------Test rewind -----------"); buffer.clear(); buffer.position(10); buffer.limit(15); System.out.println("before rewind:"+buffer); buffer.rewind(); System.out.println("after rewind:"+buffer); System.out.println("----------Test compact -----------"); buffer.clear(); buffer.put("abcd".getBytes()); System.out.println("before compact:"+buffer); System.out.println(new String(buffer.array())); buffer.flip(); System.out.println("after flip:"+buffer); System.out.println((char)buffer.get()); System.out.println((char)buffer.get()); System.out.println((char)buffer.get()); System.out.println("after three gets:"+buffer); System.out.println("\t"+new String(buffer.array())); buffer.compact(); System.out.println("after compact:"+buffer); System.out.println("\t"+new String(buffer.array())); System.out.println("----------Test get -----------"); buffer=ByteBuffer.allocate(32); buffer.put((byte)'a').put((byte) 'b').put((byte)'c').put((byte)'d').put((byte)'e').put((byte)'f'); System.out.println("before flip:"+buffer); //转换为读取模式 buffer.flip(); System.out.println("before get:"+buffer); System.out.println((char)buffer.get()); System.out.println("after get:"+buffer); //get(index)不影响position System.out.println((char)buffer.get(2)); System.out.println("after get(index):"+buffer); byte[]dst=new byte[10]; buffer.get(dst,0,2); System.out.println("after get(dst,0,2):"+buffer); System.out.println("\t dst:"+new String(dst)); System.out.println("buffer now is:"+buffer); System.out.println("\t"+new String(buffer.array())); System.out.println("----------Test put -----------"); ByteBuffer bb=ByteBuffer.allocate(32); System.out.println("before put(byte):"+bb); System.out.println("after put(byte):" + bb.put((byte) 'z')); System.out.println("after put(2,(byte)'c'):"+ bb.put(2, (byte) 'c')); System.out.println("\t"+new String(bb.array())); //这里的buffer是abcdef[pos=3 limit=6 cap=32] bb.put(buffer); System.out.println("after put(buffer):"+bb); System.out.println("\t"+new String(bb.array())); }
阅读全文
1 0
- 缓冲区 buffer
- 缓冲区(Buffer)
- NIO - Buffer缓冲区
- buffer(缓冲区模式)
- NIO - Buffer缓冲区
- 环形缓冲区 -- circular buffer
- Node.js 缓冲区 Buffer
- Buffer overflows 缓冲区溢出
- Node.js Buffer(缓冲区)
- Node.js Buffer(缓冲区)
- Node.js Buffer(缓冲区)
- 缓冲区与Buffer
- Node.js Buffer(缓冲区)
- c++缓冲区buffer
- Node.js Buffer(缓冲区)
- Buffer cache(缓冲区缓存)
- Java NIO3:缓冲区Buffer
- Ring Buffer (circular Buffer)环形缓冲区简介
- 计算机组成原理个人笔记(一)
- setObjectColor技巧
- iscsi的基本用法
- java语言基础-如何设计方法
- [转]ubuntu 服务器搭建 Shadowsocks 服务
- 缓冲区(Buffer)
- 获得Animator当前播放的AnimationClip
- 多边形重心问题 NYOJ 3 思路+代码
- 如何解决Bat脚本中包含中文,运行乱码
- Levelhead项目-实战总结
- jsp数据交互
- Python os模块常用功能
- java语言基础-方法重载
- Java日期工具类