欢迎访问www.allbetgaming.com!

首页科技正文

欧博亚洲注册:Java NIO之Buffer的使用

admin2020-09-0964

目录

  • Buffer简介
  • Buffer的焦点属性
  • Buffer的建立与使用(ByteBuffer为例)
  • 总结
  • 参考资料

Buffer简介

缓冲区(Buffer):本质上是一个数组,用于暂且保留、写入以及读取数据。在Java NIO中,
该内存块包含在NIO Buffer工具当中,NIO Buffer工具还提供了一组接口来接见该内存块。

凭据数据类型的差别,Java为除了boolean类型之外的其余7种基本类型提供了响应类型的缓冲区,
分别是ByteBufferCharBufferShortBufferIntBufferLongBuffer
FloatBufferDoubleBuffer。他们都继续自抽象类Buffer类,他们的治理方式也都险些一样。
UML类图如下:

Buffer的焦点属性

BUffer类的部门实现如下:

public abstract class Buffer {
    // Invariants: mark <= position <= limit <= capacity
    private int mark = -1;
    private int position = 0;
    private int limit;
    private int capacity;

    //组织方式
    Buffer(int mark, int pos, int lim, int cap) {       // package-private
        if (cap < 0)
            throw new IllegalArgumentException("Negative capacity: " + cap);
        this.capacity = cap;
        limit(lim);
        position(pos);
        if (mark >= 0) {
            if (mark > pos)
                throw new IllegalArgumentException("mark > position: ("
                                                   + mark + " > " + pos + ")");
            this.mark = mark;
        }
    }
    
    /**
     * Returns this buffer's capacity.
     *
     * @return  The capacity of this buffer
     */
    //返回这个Buffer的容量
    public final int capacity() {
        return capacity;
    }

    /**
     * Returns this buffer's position.
     *
     * @return  The position of this buffer
     */
    //返回这个Buffer中当前的位置(当前操作数)
    public final int position() {
        return position;
    }

    /**
     * Returns this buffer's limit.
     *
     * @return  The limit of this buffer
     */
    //返回当前Buffer中可以被操作的元素的个数
    public final int limit() {
        return limit;
    }

    /**
     * Sets this buffer's mark at its position.
     *
     * @return  This buffer
     */
    //纪录当前position的位置
    public final Buffer mark() {
        mark = position;
        return this;
    }
    
    public final Buffer reset() {
        int m = mark;
        if (m < 0)
            throw new InvalidMarkException();
        position = m;
        return this;
    }

}

其中界说了四个Buffer属性,对应的形貌如下

属性 形貌
capacity 容量;用于形貌这个Buffer巨细,即建立的数组的长度,一旦声明不能以被改变
position 位置,示意当前缓冲区中正在操作的数据的位置,在切换读取时会将其置0
limit 界线、限制;示意当前缓冲区中可以操作的数据的巨细,默认情形下为Buffer的巨细,切换为读取模式后为数组中元素的个数(准确的说时切换之前position的值)
mark 符号;用于纪录当前position的位置,后续操作历程中可以使用reset()方式将position还原至最后一次mark的位置

Buffer的建立与使用(ByteBuffer为例)

Buffer的建立

Java NIO中可以使用对应Buffer类的allocate()或者allocateDirect()静态方式建立。

//使用allocate()建立
ByteBuffer byteBuffer=ByteBuffer.allocate(1024);

//使用allocateDirect()建立
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(1024);

Buffer的本质是一个数组,建立时需要指定数组的巨细

Buffer的使用

Buffer的使用一样平常分为四个步骤

  1. Buffer中写入数据
  2. Buffer切换为读取模式
  3. 读取Buffer
  4. Buffer清空,供后续写入使用

1. 写如数据

//使用put()方式向Buffer中写入数据
byteBuffer.put("bmilk".getBytes());

//使用Channel#read()向Buffer中写入数据
channel.read(byteBuffer);

2. 将Buffer切换为读取模式

可以通过挪用flip()方式将Buffer从写模式切换到读模式。

byteBuffer.flip()

挪用flip()方式会将position设回0,并将limit设置成之前position的值。
即,现在使用position符号读的位置,limit示意之前写进了多少个byte,也就是现在
能读取多少个byte等。

3. 读取Buffer
读取Buffer有两种方式:

  1. Buffer种读取数据到Channel
  2. 使用get()方式从Buffer种读取数据
//从Buffe中将数据写入通道
inChannel.write(byteBuffer)

//使用get()方式从BUffer中读取数据
byte[] bytes=new byte[byteBuffer.limit()];
byteBuffer.get(bytes);

4. 将Buffer清空,供后续写入使用
使用clear()清空缓冲区,清空缓冲区只是使各个指针恢复初始位置,
更详细的说是position设置为0,limit设置为容量的初始巨细。
并不会真实清空其中数据,然则可以通过后续的写笼罩之前的数据

byteBuffer.clear()

其他的一些方式

  1. 使用rewind()Buffer重复读取数据
//使用`rewind()`从`Buffer`重复读取数据
//Buffer.rewind()将position设回0,以是你可以重读Buffer中的所有数据。
//limit保持稳定,仍然示意能从Buffer中读取多少个元素(byte、char等)。
Buffer rewind = byteBuffer.rewind();
  1. compact()方式

clear()会使使各个指针恢复初始位置,然则现实中可能存在部门数据还没有被使用,而后续需要使用。
又必须清算一部门Buffer的空间,compact()方式会将所有未读数据拷贝到Buffer的起始处,
然后将position指针设置到最后一个未读元素的后面,现在Buffer可以举行写数据,
然则不会笼罩前面的未读的数据。

  1. mark()方式与reset()方式

通过挪用Buffer.mark()方式,可以符号Buffer中的当前的position。之后可以通过挪用Buffer.reset()方式恢复到这个position。

//使用mark符号当前的position位置
byteBUffer.mark()
//使用reset方式使position指针返回这个位置
byteBuffer.reset()

4.equals()方式与compareTo()方式

当需要对照两个Buffer时可以使用equals()方式与compareTo()方式。

equals()方式判断两个方式是否相等,当知足下列条件时,示意两个Buffer相等

  • 有相同的类型(bytecharint等)
  • Buffer中剩余的bytechar等的个数相等。
  • \(\color{#FF3030}{`Buffer`中所有剩余的`byte`、`char`等都相同}\)

compareTo()方式对照两个两个Buffer的巨细,仅对照剩余元素(bytechar等)
若是知足下列条件,则以为一个Buffer“小于”另一个Buffer

  • 第一个不相等的元素小于另一个Buffer中对应的元素
  • 所有元素都相等,但第一个Buffer比另一个先耗尽(第一个Buffer的元素个数比另一个少)。

直接缓冲区与非直接缓冲区

  • 非直接缓冲区:通过allocate()方式分配缓冲区,将缓冲区建立在JVM内存中
  • 直接俄缓冲区:通过allocateDirect()方式分配直接缓冲区,将缓冲区建立在物理内存中,可以在某些情形下提高效率

非直接缓冲区

  • 非直接缓冲区数据流向图

直接缓冲区

  • 直接缓冲区数据流向图

直接缓冲区(物理内存映射文件):相比非直接缓冲区省略了copy的历程,以是说直接缓区可以一定程度上提高效率

坏处:

  • 开拓空间时资源消耗大
  • 不安全,java程序将数据写入物理内存映射文件中,之后数据将不受Java程序控制,
    什么时候写入硬盘无法控制(由操作系统控制),当垃圾接纳机制释放引用后才气断开与之的毗邻

小结

  • 缓冲区要么是直接的,要么是非直接的若是为直接字节缓冲区,则java虚拟机会见最大起劲直接在此缓冲区上执行本机I/O
    也就是说,每次挪用基础操作系统的I/O之前或之后,虚拟机都回只管制止将缓冲区的内容复制到中心缓冲区或者从中心缓冲区中复制内容。
  • 直接字节缓冲区可以通过挪用此类的allocateDirect()工厂方式来建立,
    此方式返回的缓冲区举行分配和作废分配所需的程本通常高于非直接缓冲区,
    直接缓冲区的内容可以驻留在通例的垃圾接纳堆之外,因此他们对应用程序内存需求造成的影响可能并不显著,
    以是建议直接缓冲区主要分配给易受基础系统的本机I/O操作影响的大型、持久得缓冲区。
    一样平常情形下,最好尽在直接缓冲区能在程序性能方面带来显著利益时分配他们。
  • 直接字节缓冲区还可以通过FileChannelmap()方式,将文件区域直接映射到内存中来建立,
    该方式返回MappedByteBufferJava的实现有助于JNI从内陆及代码建立直接字节缓冲区,
    若是以上这些缓冲区中的某个缓冲区实例指的是不能接见的内存区域。
    则试图接见该区域不会更改缓冲区的内容,而且将会在接见期间或稍后的时间导致抛出不确定的异常
  • 字节缓冲区是直接缓冲区还是非直接缓冲区可以通过挪用其isDirect()方式来确定,提供此方式是为了能够在性能要害型代码中执行显式缓冲区治理。

总结

本文简朴先容了Buffer的种类,并对常用方式举行乐简朴的先容

参考资料

Java NIO系列教程(三) Buffer

,

欧博开户www.allbetgame.us

欧博开户www.allbetgame.us

本文链接:https://www.lphggs.com/post/963.html

网友评论

2条评论
  • 2020-07-20 00:00:03

    欧博亚洲欢迎进入欧博亚洲(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。很棒啊这个

    • 2020-09-08 13:13:48

      @UG环球手机版下载 欧博allbet网址欢迎进入欧博allbet网址(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。萌新来了,眼熟我

最新评论

  • UG环球手机版下载 09/24 说:

    Allbet代理欢迎进入Allbet代理(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。今天下雨,躲在家里看

  • allbet在线 09/24 说:

    Allbet开户欢迎进入Allbet开户(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。保质保量的内容

  • 环球UGAPP下载 09/24 说:

    www.allbetgaming.net欢迎进入欧博平台网站(www.aLLbetgame.us),www.aLLbetgame.us开放欧博平台网址、欧博注册、欧博APP下载、欧博客户端下载、欧博游戏等业务。已中毒,还能更深

  • UG环球网址 09/23 说:

    apple developer enterprise account for rentproviding apple enterprise developer accounts for rent, rent your own enterprise account for app signing. with high quality, stable performance and affordable price.经夸吗?我来了!!

  • 环球UG网址 09/23 说:

    环球UG欢迎进入环球UG官网(UG环球):www.ugbet.us,环球UG官方网站:www.ugbet.net开放环球UG网址访问、环球UG会员注册、环球UG代理申请、环球UG电脑客户端、环球UG手机版下载等业务。很不容易啊

  • 联博以太坊高度 09/22 说:

    AllbetGmaing下载欢迎进入AllbetGmaing下载(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。快来呀快来呀

  • 联博开奖 09/21 说:

    联博统计接口www.326681.com采用以太坊区块链高度哈希值作为统计数据,联博以太坊统计数据开源、公平、无任何作弊可能性。联博统计免费提供API接口,支持多语言接入。弄个交流群

  • 皇冠体育APP 09/21 说:

    欧博allbet网址欢迎进入欧博allbet网址(Allbet Game):www.aLLbetgame.us,欧博官网是欧博集团的官方网站。欧博官网开放Allbet注册、Allbe代理、Allbet电脑客户端、Allbet手机版下载等业务。好文不用推广