4

Java NIO是java用来提高java IO操作性能。基于网上的教程和一些资料对NIO的知识进行整理和总结

  1. 缓冲区Buffer

    底层是由数组实现并构成的,负责数据的存储,不同的数据类型有对应类型的缓冲区,但容量是在Buffer对象声明时指定的,Buffer对象一旦创建后,容量不能改变。常用的Buffer类型及对应的基本数据类型:

       ByteBuffer     (byte)
       CharBuffer     (char)
       ShortBuffer    (short)
       IntBuffer      (int)
       LongBuffer     (long)
       FloatBuffer    (float)
       DoubleBuffer   (double)

    不同类型的Buffer管理缓冲区的方式都一致,通过allocate()方法获取Buffer对象,且都是间接缓存区


  2. Buffer的相关属性

    position:当前正在进行处理的数据在缓冲区的位置
    limit:缓冲区中有效数据的范围
    capacity:缓冲区的最大容量
    mark:用来记录position所在的位置,与mark()、reset()方法联合使用
    例:以ByteBuffer为例

       ByteBuffer ByteBuffer = ByteBuffer.allocate(10);

    Buffer初始化后属性情况


  3. Buffer的相关常用方法

    put():向缓冲区存放数据
    例:

    byteBuffer.put("hello".getBytes());

    图片描述


    flip():切换缓冲区的读写状态,
    例:

    byteBuffer.flip();

    图片描述


    get():从缓存区获取数据
    例:

    byteBuffer.get();

    图片描述


    rewind():使用get()方法从缓冲区获取一部分或全部数据后,需要在重新从缓冲区中获取数据,需要先调用rewind()方法,然后再使用get()方法
    例:

    byteBuffer.rewind();

    图片描述


    mark():将缓冲区属性position的当前取值赋给属性mark,例:

    byteBuffer.get();
    byteBuffer.mark();
    byteBuffer.get();

    图片描述


    reset():将缓冲区属性position的值重置为之前调用mark()方法时的position的值
    例:

    byteBuffer.reset();

    图片描述


    clear():重置缓冲区属性position=0,属性limit=capacity,这样就无法获取到缓冲区中正确的数据了,但是clear()方法不会清空缓冲区中已存在的数据
    例:

    byteBuffer.clear();

    图片描述


  4. Buffer相关属性的取值范围

    0 <= mark <= position <= limit <= capacity
    
  5. 直接缓冲区

    根据缓冲区在屋里内存中的位置分为:直接缓冲区、间接缓冲区
    间接缓冲区:是在JVM的堆内存中进行创建的,JVM的GC能够管理缓冲区占用的内存。使用间接缓冲区进行IO操作数据时,需要从用户地址空间copy到内核地址空间,或是从内核地址空间copy到用户地址空间,所以IO性能没有直接缓冲区的好。图片描述


    直接缓冲区:使用ByteBuffer.allocateDirect(1024)来创建直接缓冲区,直接缓冲区只有ByteBuffer类型。独立与JVM内存之外的,存在于物理内存中的一块内存区域;不收JVM的GC管理。JVM会尽最大努力在此缓冲区上执行本机IO操作以提高IO性能。由于直接缓冲区在JVM内存之外,如果无法进行有效管理容易造成物理内存溢出,因此最好仅在直接缓冲区能在性能方面带来明显好处时使用。图片描述


  6. NIO分散读取和聚集写入

    Scattering reads:分散读取按照缓冲区的顺序依次将数据读取到应用程序中;

       read(byte[])

    Gathering writes:聚集写入按照缓冲区的顺序依次将应用程序中的数据写入到缓冲区中:

       write(byte[])
  7. NIO字符集

    编码:字符串转换成字节数组的过程
    解码:字节数组转换成字符串的过程
    解码和编码过程中,字符串与字节数组相互转换使用到的字符集;通过Chartset.forName(charsetName)方法进行声明


浪一把
112 声望5 粉丝