NIO
1、NIO与IO的区别

| IO流 | NIO流 |
|---|---|
| 面向字节流 | 面向缓冲区 |
| 阻塞 | 非阻塞 |
| 管道是单向的 | 管道是双向的 |
阻塞和非阻塞关注的是**程序在等待调用结果(消息,返回值)时的状态.**
阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有在得到结果之后才会返回。
非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。
说人话就是:
阻塞是我啥事不做等你回来。
非阻塞就是你还没回来那我先做其他事,偶尔确认下你回来了没。
2、缓冲区
2.1、缓冲区是什么
缓冲区(buffer):是一个在内存空间中具有一定大小的存储空间。这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区。
2.2、不同类型的缓冲区

如图所示:缓冲区有7种不同数据类型,用于存储不同数据类型的数据

2.3、缓冲区的四个重要属性
从源码查看:

分别就是:
-
mark(标记):在某个位置进行标记,例如打游戏时,在某个地方进行一个存档。
-
position(位置):表示缓存区中正在操作数据的位置。
-
limit(界限):表示缓存区中可以被我们操作的数据的大小。
-
capacity(容量):缓存区能够容纳的数据元素的最大数量,一旦声明不能改变。
2.4、缓冲区的基本操作
缓冲区的基本操作:
-
allocate(int capacity):分配大小
-
put():写数据
-
flip():可以理解为从写模式转换到读模式
注意:
对缓冲区写入“ousigao”这个长度为7的字符串后,此时缓冲区的position是在7的这个位置(因为0~6这7个位置都被占满了),此时,如果直接读数据会出现出现异常,所以用flip()来使position从0开始,此外因为可读的数据长度为7,所以limit也设为7,同时取消mark标记。
-
get():读数据
-
rewind()(重读):将当前的position设置为0,同时取消mark标记。
-
clear():清除数据,同时取消mark标记,但其实是将缓冲区还原成一开始的样子。
注意:
其实数据还在,本质就是把缓冲区的position,limit恢复成原来的样子。
- reset():到mark标记的位置,就如同游戏存完档后的读档。
2.5、Demo展示
public class BufferDemo {
public static void main(String[] args) {
System.out.println("---------------------allocate操作-----------------------------");
ByteBuffer buf = ByteBuffer.allocate(1024) ;
System.out.println("capacity: =>" + buf.capacity()); // capacity: =>1024
System.out.println("position: =>" + buf.position()); // position: =>0
System.out.println("limit: =>" + buf.limit()); // limit: =>1024
System.out.println("------------------------put操作-------------------------------");
String test = "ousigao" ;
buf.put(test.getBytes()) ;
System.out.println("capacity: =>" + buf.capacity()); // capacity: =>1024
System.out.println("position: =>" + buf.position()); // position: =>7
System.out.println("limit: =>" + buf.limit()); // limit: =>1024
System.out.println("------------------------flip操作------------------------------");
buf.flip() ;
System.out.println("capacity: =>" + buf.capacity()); // capacity: =>1024
System.out.println("position: =>" + buf.position()); // position: =>0
System.out.println("limit: =>" + buf.limit()); // limit: =>7
System.out.println("------------------------get操作-------------------------------");
byte[] getData = new byte[buf.limit()] ;
buf.get(getData) ;
System.out.println("Data=>" + new String(getData,0,getData.length)); // Data=>ousigao
System.out.println("-----------------------rewind操作-----------------------------");
buf.rewind() ;
System.out.println("capacity: =>" + buf.capacity()); // capacity: =>1024
System.out.println("position: =>" + buf.position()); // position: =>0
System.out.println("limit: =>" + buf.limit()); // limit: =>7
System.out.println("-----------------------clear操作-----------------------------");
buf.clear() ;
System.out.println("capacity: =>" + buf.capacity()); // capacity: =>1024
System.out.println("position: =>" + buf.position()); // position: =>0
System.out.println("limit: =>" + buf.limit()); // limit: =>1024
System.out.println("-----------------------reset操作-----------------------------");
String testReset = "testReset" ;
buf.put(testReset.getBytes()) ;
System.out.println("capacity: =>" + buf.capacity()); // capacity: =>1024
System.out.println("position: =>" + buf.position()); // position: =>9
System.out.println("limit: =>" + buf.limit()); // limit: =>1024
buf.mark() ;
String testReset1 = "testReset1" ;
buf.put(testReset1.getBytes()) ;
System.out.println("capacity: =>" + buf.capacity()); // capacity: =>1024
System.out.println("position: =>" + buf.position()); // position: =>19
System.out.println("limit: =>" + buf.limit()); // limit: =>1024
buf.reset() ;
System.out.println("capacity: =>" + buf.capacity()); // capacity: =>1024
System.out.println("position: =>" + buf.position()); // position: =>9
System.out.println("limit: =>" + buf.limit()); // limit: =>1024
}
}
浙公网安备 33010602011771号