Java NIO提供了与标准IO不同的IO工作方式: 
        Channels and Buffers(通道和缓冲区):标准的IO基于字节流和字符流进行操作的,而NIO是基于通道(Channel)和缓冲区(Buffer)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。

        Asynchronous IO(异步IO):Java NIO可以让你异步的使用IO,例如:当线程从通道读取数据到缓冲区时,线程还是可以进行其他事情。当数据被写入到缓冲区时,线程可以继续处理它。从缓冲区写入通道也类似。

        Selectors(选择器):Java NIO引入了选择器的概念,选择器用于监听多个通道的事件(比如:连接打开,数据到达)。因此,单个的线程可以监听多个数据通道。

 

Buffer

    为什么需要buffer:计算机CPU已经不是程序运行的瓶颈,程序大多数时候都在等待数据,向网卡/硬盘等硬件设备读写数据,因此I/O操作具有很大的性能优化空间。使用缓存进行批量的I/O操作可以减少CPU运算与I/O之间的切换,提高CPU运算模块的利用率。

    程序标准buffer:

    由于程序不能直接操纵硬件,早期程序操作内存如下图:

    

java bufferWrite写会计 java io buffer_python

    在现代计算机系统中,采用虚拟内存地址技术,将程序使用的内存映射到物理内存与高速磁盘中,比如linux中的swap空间,windows中的虚拟内存配置等。由此带来了内存操作的优化:

    

java bufferWrite写会计 java io buffer_运维_02

    java buffer:

    类名: java.nio.buffer   , 子类:

    

java bufferWrite写会计 java io buffer_java_03

    buffer要素:容量(capacity,buffer申请的内存大小),大小(limit 可读写的大小),位置(get,put方法所在的下标),标记(mark),读写(get,put)。

大小关系: 0<=mark<=position<=limit<=capacity

Java buffer的特性:

    · buffer可以是只读的,也可以是可读写的,由asReadOnlyBuffer()转化。

    · buffer可以以数组形式做转存:buffer.wraps()

ByteBuffer与其他buffer有一定区别:

    1. byteBuffer可以与其他基本类型buffer数据转化,它具有putChar(), getChar()等方法实现单个数值的转化,又有asCharBuffer()方法将整个缓存区转为charBuffer使用。

    2. byteBuffer允许直接使用系统内存,这样的内存不受JVM垃圾回收的管理,使用时候需要注意回收内存。ByteBuffer.allocateDirect(int capacity)。  

  样例代码:

    

java bufferWrite写会计 java io buffer_Java_04

Buffer常用操作:

buffer.position() 无参数,返回当前position位置;int X参数,将position置为X

buffer.get() 无参数,取出当前position的值并position++;int X参数,取出position位置X的值

buffer.put() 1参数,写入当前position的值并position++;2参数,写入position位置X的值

buffer.flip() 将position置为0,limit=position

buffer.compact() 若position之前有值将position之前的值抛弃,将position置为limit-position+1 即把position与limit之间的空间放到0 - position中间。

buffer.clear() position置为0,limit=capacity

buffer.hasRemaining() 返回true表示下一位的值不为空,用来判断position - limit 之间是否有值

    buffer.remaining() 返回当前位置到limit之间有值的个数