• Java NIO之缓冲区Buffer


    Java NIO的核心部件:

    Buffer

    Channel

    Selector

    Buffer

    是一个数组,但具有内部状态。如下4个索引:

    • capacity:总容量
    • position:下一个要读取/写入的元素索引
    • limit:限制,第一个不能读取/写入的元素索引
    • mark:位置标记,重置position
    • //通过调用Buffer.mark()方法,可以标记Buffer中的一个特定position。之后可以通过调用Buffer.reset()方法恢复到这个position//
    • 0 <= mark <= position <= limit <= capacity

    用例:

    初始状态:

    image

    初始如上图,添加数据:put()方法会改变position的值,但put(int,object)不会改变

    buffer.put((byte) H).put((byte) e).put((byte) l).put((byte) l).put((byte) o);

    image

    在上图的基础上进行flip()操作,则会进入下面的状态:

    image

    flip:将缓冲区准备为数据传出状态,即limit=position,position=0

    在上图基础上,进行get操作,position会后移,知道position=limit,如下图:

    image

    在上图基础上,进行rewind()的操作,position为0,limit不变,如下图,如需多次读取缓冲区数据,可以在两次读取之间使用rewind()。

    image

    假设新的状态如下图:

    image

    在新状态下进行compact()操作,进入下面状态

    image

    在新状态下进行clear()操作,返回到初始状态,即position=0,limit=capacity

    image

    Buffer的类型:

    • ByteBuffer
    • MappedByteBuffer
    • CharBuffer
    • DoubleBuffer
    • FloatBuffer
    • IntBuffer
    • LongBuffer
    • ShortBuffer

    Buffer的分配:工厂方法

    1、allocate

    //申请48字节

    ByteBuffer buf = ByteBuffer.allocate(48);

    //申请1024字符

    CharBuffer buf = CharBuffer.allocate(1024);

    2、wrap,包装一个已有的数组

    char [] myArray = new char [100];
    CharBuffer charbuffer = CharBuffer.wrap (myArray);
    注意,这样的方式创建的Buffer,将不会在堆上创建新的数组,而是直接利用myArray做backing store,这意味着任何对myArray或者buffer的修改都将影响到buffer或者myArray。

    3、复制Buffer“浅拷贝”

    • a)通过duplicate()方法将返回一个新创建的buffer,这个新buffer与原来的Buffer共享数据,一样的capacity,但是有自己的position、limit和mark属性。
    • b)通过asReadOnlyBuffer()方法复制的buffer与duplicate()类似,是只读的,不能调用put。
    • c)slice()方法,故名思议,类似切割一个Buffer出来,与duplicate类似,但是它将从原来Buffer的当前position开始,并且capacity等于原来Buffer的剩余元素数目,也就是(limit-position)。

    向Buffer写数据

    从channel写入到Buffer

    int bytesRead = inChannel.read(buf);

    通过Buffer的put方法写入

    buf.put(127);

    相对位置:在position之后写入数据,并改变position

    put(byte b);

    put(byte[] src);

    put(byte[] src, int offset, int length);

    put(ByteBuffer src);

    绝对位置:提供写入的位置,并不改变position值。

    put(int index, byte b);

    从Buffer读数据

    从channel读出数据

    int bytesWritten = inChannel.write(buf);

    通过Buffer的get方法

    相对位置

    get()

    get(byte[] dst);

    get(byte[] dst, int offset, int length);

    绝对位置

    get(int index);

  • 相关阅读:
    JavaScript中的__proto__
    移动前端调试页面–weinre
    nodo合并多个mp3文件
    enctype和Content-type有什么关系
    vscode 实用的插件
    前端跨域问题及解决方案
    小小的js
    如何使用eslint
    RN记录
    numpy的索引
  • 原文地址:https://www.cnblogs.com/dorothychai/p/4178530.html
Copyright © 2020-2023  润新知