NIONIO和IO的比较以及缓冲区

Posted xdcat

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NIONIO和IO的比较以及缓冲区相关的知识,希望对你有一定的参考价值。

NIO v.s. IO

传统IO:

  • 面向流
  • 属于阻塞IO
  • 单向管道传输:输入流、输出流

NIO:

  • 面向缓冲区
  • 属于非阻塞IO
  • 使用缓冲区在通道内传输

缓冲区

缓冲区在NIO中负责数据的存取,缓冲区就是数组,用于存储不同数据类型的值,除了boolean,都有相应类型的缓冲区。

缓冲区的核心方法:取get()、存put()

技术图片

4个核心属性

  • capacity:表示缓冲区中最大存储数据的容量,一旦声明不能改变。因为buffer的底层是数组,数据的容量初始化后就不能改变了。
  • limit:表示缓冲区中可以操作数据的大小,limit之后的数据不可以进行读写。
  • position:表示缓冲区正在操作的数据的位置
  • mark:记录当前position的位置,额可以通过reset()恢复到mark的位置

0 <= mark <= position <= limit <= capacity

常用方法:

  • rewind():可重复读
  • flip():切换读模式
  • mark():标记
  • reset():恢复到mark的位置
  • clear():清空缓冲区,但数据依然存在,position、limit、capacity的位置恢复初始状态
  • remain():获取缓冲区可以操作的数量

直接缓冲区 v.s. 非直接缓冲区

非直接缓冲区:

  • 通过allocate()方法分配,将缓冲区建立在JVM的内存中
  • 数据传输过程:写入数据时,应用程序写入用户地址空间的缓存中,然后拷贝到内核地址空间的缓存中,再写入物理磁盘。读取数据时,从物理磁盘读取到内存地址空间中,再拷贝到用户地址空间的缓存中,最后读入程序中。
  • 底层是通过创建一个HeapXXXBuffer实现

直接缓冲区:

  • 通过allocateDirect()方法分配,将缓冲区建立在物理内存中
  • 数据传输过程:通过物理内存映射文件直接读写
  • 底层是通过创建一个DirectXXXBuffer实现

二者比较:各有利弊,直接缓冲区读写效率高,但是不安全,内存消耗大。

isDirect()方法可以用来判断是否是直接缓冲区

 

以上是关于NIONIO和IO的比较以及缓冲区的主要内容,如果未能解决你的问题,请参考以下文章

IO流25 - 字符流 - 字符输出流的缓冲流以及字符输入流的缓冲流BufferedWriter和BufferedReader

JVM--11---直接内存

Java IO—缓冲字符流以及IO中的装饰者模式

字节流复制文件和字节缓冲流复制文件的时间比较

网络IO模型

IO流23 - 字节流 - 字节输出流的缓冲流以及字节输入流的缓冲流BufferedOutputStream&BufferedInputStream