博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
2、NIO--缓冲区(Buffer)
阅读量:6714 次
发布时间:2019-06-25

本文共 9179 字,大约阅读时间需要 30 分钟。

 

缓冲区(BUffer)

缓冲区(Buffer:一个用于特定基本数据类

型的容器。由 java.nio 包定义的,所有缓冲区
都是 Buffer 抽象类的子类。

 

Java NIO 中的 Buffer 主要用于与 NIO 通道进行

交互,数据是从通道读入缓冲区,从缓冲区写
入通道中的。

 

缓冲区:在NIO中负责数据的存取,说白了就是数组用于储存不同类型的数组

根据数据类型不同(boolean类型除外),提供了相应的类型的缓冲区

 ByteBuffer

 CharBuffer
 ShortBuffer
 IntBuffer
 LongBuffer
 FloatBuffer
 DoubleBuffer

 

上述Buffer类他们都采用相拟的方法进行管理数据

只是各自管理的数据类不同而已

 

的都是通过同一个方法获取Buffer对象:

static XxxBuffer allocate(int capacity) : 创建一个容量为 capacity 的 XxxBuffer 对象

ByteBuffer buf = ByteBuffer.allocate(1024);

  

缓冲区存取数据的两个核心方法:

1、put():存入数据到缓冲区

public final ByteBuffer put(byte[] src) {        return put(src, 0, src.length);    }
public ByteBuffer put(byte[] src, int offset, int length) {        checkBounds(offset, length, src.length);        if (length > remaining())            throw new BufferOverflowException();        int end = offset + length;        for (int i = offset; i < end; i++)            this.put(src[i]);        return this;    }

 

 

 

 

2、get():获取缓冲区中的数据

public ByteBuffer get(byte[] dst) {        return get(dst, 0, dst.length);    }
public ByteBuffer get(byte[] dst, int offset, int length) {        checkBounds(offset, length, dst.length);        if (length > remaining())            throw new BufferUnderflowException();        int end = offset + length;        for (int i = offset; i < end; i++)            dst[i] = get();        return this;    }

 

缓冲区中的四个核心属性

public abstract class java.nio.Buffer {    // Field descriptor #20 I  static final int SPLITERATOR_CHARACTERISTICS = 16464;    // Field descriptor #20 I  private int mark;    // Field descriptor #20 I  private int position;    // Field descriptor #20 I  private int limit;    // Field descriptor #20 I  private int capacity;  ...

容量 (capacity) :表示 Buffer 最大数据容量,缓冲区容量不能为负,并且创

  建后不能更改。

限制 (limit):第一个不应该读取或写入的数据的索引,即位于 limit 后的数据
  不可读写。缓冲区的限制不能为负,并且不能大于其容量

位置 (position):下一个要读取或写入的数据的索引。缓冲区的位置不能为
  负,并且不能大于其限制

标记 (mark)与重置 (reset):标记是一个索引,通过 Buffer 中的 mark() 方法
  指定 Buffer 中一个特定的 position,之后可以通过调用 reset() 方法恢复到这
  个 position.

标记、位置、限制、容量遵守以下不变式: 0 <= mark <= position <= limit <= capacity

 

public static void main(String[] args) {                //1、分配一个指定大小的缓冲区        ByteBuffer buf = ByteBuffer.allocate(1024);                System.out.println(buf.position());//0        System.out.println(buf.limit());//1024        System.out.println(buf.capacity());//1024        System.out.println(buf.mark());//java.nio.HeapByteBuffer[pos=0 lim=1024 cap=1024]   }

 

 

 

相关测试以及源码

1、--------------------------------------------------------

allocate源码:

public static ByteBuffer allocate(int capacity) {        if (capacity < 0)            throw new IllegalArgumentException();        return new HeapByteBuffer(capacity, capacity);    }

 

HeapByteBuffer(int cap, int lim) {            // package-private        super(-1, 0, lim, cap, new byte[cap], 0);        /*        hb = new byte[cap];        offset = 0;        */    }

 

public static void main(String[] args) {                //1、分配一个指定大小的缓冲区        ByteBuffer buf = ByteBuffer.allocate(1024);                System.out.println(buf.position());//0        System.out.println(buf.limit());//1024        System.out.println(buf.capacity());//1024        System.out.println(buf.mark());//java.nio.HeapByteBuffer[pos=0 lim=1024 cap=1024]                //2、利用put()方法进行存储数据        String str = "hello nio";        buf.put(str.getBytes());                System.out.println(buf.position());//9        System.out.println(buf.limit());//1024        System.out.println(buf.capacity());//1024        System.out.println(buf.mark());//java.nio.HeapByteBuffer[pos=9 lim=1024 cap=1024]    }

 

2、--------------------------------------------------------

public static void main(String[] args) {                //1、分配一个指定大小的缓冲区        ByteBuffer buf = ByteBuffer.allocate(1024);                System.out.println(buf.position());//0        System.out.println(buf.limit());//1024        System.out.println(buf.capacity());//1024        System.out.println(buf.mark());//java.nio.HeapByteBuffer[pos=0 lim=1024 cap=1024]                //2、利用put()方法进行存储数据        String str = "hello nio";//9字节        buf.put(str.getBytes());                System.out.println(buf.position());//9        System.out.println(buf.limit());//1024        System.out.println(buf.capacity());//1024        System.out.println(buf.mark());//java.nio.HeapByteBuffer[pos=9 lim=1024 cap=1024]                //3、切换读取数据的模式        buf.flip();        System.out.println(buf.position());//0        System.out.println(buf.limit());//9        System.out.println(buf.capacity());//1024        System.out.println(buf.mark());//java.nio.HeapByteBuffer[pos=0 lim=9 cap=1024]                //4、利用get()方法读取数据        byte dst [] = new byte[buf.limit()];        buf.get(dst);        System.out.println(new String(dst,0,dst.length));//hello nio                System.out.println(buf.position());//9        System.out.println(buf.limit());//9        System.out.println(buf.capacity());//1024        System.out.println(buf.mark());//java.nio.HeapByteBuffer[pos=9 lim=9 cap=1024] }

 

 

关于flip源码:

public final Buffer flip() {        limit = position;        position = 0;        mark = -1;        return this;    }

实际上是将position的值赋值给limit

在将position的值置为0

 

3、--------------------------------------------------------

public static void main(String[] args) {                //1、分配一个指定大小的缓冲区        ByteBuffer buf = ByteBuffer.allocate(1024);                System.out.println(buf.position());//0        System.out.println(buf.limit());//1024        System.out.println(buf.capacity());//1024        System.out.println(buf.mark());//java.nio.HeapByteBuffer[pos=0 lim=1024 cap=1024]                //2、利用put()方法进行存储数据        String str = "hello nio";        buf.put(str.getBytes());                System.out.println(buf.position());//9        System.out.println(buf.limit());//1024        System.out.println(buf.capacity());//1024        System.out.println(buf.mark());//java.nio.HeapByteBuffer[pos=9 lim=1024 cap=1024]                //3、切换读取数据的模式        buf.flip();        System.out.println(buf.position());//0        System.out.println(buf.limit());//9        System.out.println(buf.capacity());//1024        System.out.println(buf.mark());//java.nio.HeapByteBuffer[pos=0 lim=9 cap=1024]                //4、利用get()方法读取数据        byte dst [] = new byte[buf.limit()];        buf.get(dst);        System.out.println(new String(dst,0,dst.length));//hello nio                System.out.println(buf.position());//9        System.out.println(buf.limit());//9        System.out.println(buf.capacity());//1024        System.out.println(buf.mark());//java.nio.HeapByteBuffer[pos=9 lim=9 cap=1024]                //5、rewind()回到读模式(可重复读数据)        buf.rewind();        System.out.println(buf.position());//0        System.out.println(buf.limit());//9        System.out.println(buf.capacity());//1024        System.out.println(buf.mark());//java.nio.HeapByteBuffer[pos=0 lim=9 cap=1024]    }

rewind():回到读模式(可重复读取数据)

相关源码:

 

public final Buffer rewind() {        position = 0;        mark = -1;        return this;    }

 

 

 

此时是将position的值置为-1

 

 

4、--------------------------------------------------------

继上述代码继续添加代码:

//6、清空缓冲区        buf.clear();        System.out.println(buf.position());//0        System.out.println(buf.limit());//1024        System.out.println(buf.capacity());//1024        System.out.println(buf.mark());//java.nio.HeapByteBuffer[pos=0 lim=1024 cap=1024]

清空缓冲区之后将会回到初始化状态

clear()方法源码:

将position的值置为0

将capacity的值赋值给limit

此将重新进入新创建的缓冲区

public final Buffer clear() {        position = 0;        limit = capacity;        mark = -1;        return this;    }

 

缓冲区的数据依然存在,但是处于“被遗忘的数据”(位置界限等都变了)

 

5、--------------------------------------------------------

再次进行添加代码:

buf.get(dst);        System.out.println(new String(dst,0,dst.length));//hello nio

 

 

关于标记和重置的使用

@Test    public void test(){        ByteBuffer buf = ByteBuffer.allocate(1024);                String str="abcde";        buf.put(str.getBytes());                //切换到读取数据模式        buf.flip();                //读取数据        byte dst [] = new byte[buf.limit()];        buf.get(dst,0,2);        System.out.println("第一次打印操作");        System.out.println(buf.position());        System.out.println(new String(dst,0,2));                //进行标记        buf.mark();                //再次进行读取数据        buf.get(dst,2,2);        System.out.println("第二次打印操作");        System.out.println(buf.position());        System.out.println(new String(dst,2,2));                //恢复到之前的位置        buf.reset();        System.out.println("恢复到第一次操作备份的位置");        System.out.println(buf.position());    }

mark()的源码:

public final Buffer mark() {        mark = position;        return this;    }

 

reset()方法源码:

public final Buffer reset() {        int m = mark;        if (m < 0)            throw new InvalidMarkException();        position = m;        return this;    }

 

 再次添加新的代码:

//判断缓冲区是否还有剩余数据        if(buf.hasRemaining()){            //获取缓冲区可操作的数据的数量            System.out.println(buf.remaining());        }

hasReaining()方法的源码:

public final boolean hasRemaining() {        return position < limit;    }

 

 

此前有一个恢复到第一次操作数据的位置

所以此时可以操作的数据剩余量为3

 

图解缓冲区的基本属性(position、capacity、limit)

 

缓冲区常常使用的方法

 

转载于:https://www.cnblogs.com/Mrchengs/p/10817276.html

你可能感兴趣的文章
WinAircrackPack 破解你邻居家的无线WIFI密码
查看>>
自定义格式化字符串
查看>>
bgp发布路由对端无法收到,原因是使用默认网段
查看>>
JQuery实现简单的服务器轮询效果
查看>>
幽灵漏洞(GHOST)影响大量Linux操作系统及其发行版(更新修复方案)
查看>>
Sunday算法
查看>>
netstat
查看>>
优朋普乐:OTT正重构电视版图
查看>>
遇到"process launch failed: Security"问题,解决的一种方法
查看>>
Ubuntu 14.04 LTC 有线网络——网线不识别,灯不亮问题
查看>>
Unity3D DLL加密
查看>>
ubuntu root用户的密码
查看>>
linux ssh配置与禁用root远程登录
查看>>
Ngios plugin for cacti(NPC)
查看>>
求数组中最长递增子序列
查看>>
前端开发面试题(收集贴)
查看>>
Spring Boot cache backed redis
查看>>
有趣的编程----控制自己电脑的CPU
查看>>
linux的目录结构
查看>>
Java中创建对象的5种不同方法
查看>>