在学习Java的过程中,相信大家都有学过IO流吧?那NIO大家有没有了解呢?今天我们就来看看强大的NIO。对比IO流,看看哪个更加强大。
NIO与IO的主要区别
废话不多说,我们来看一张表
面向流
面向流的数据传输是在管道建立连接后单向进行数据传输,在我们学习Java的时候InputStream和OutputStream就是对应输入流和输出流,它们的传输方向是单向的。
面向缓冲区
面向缓冲区的数据传输是在通道建立连接后通过缓冲区进行数据的双向传输。缓冲区就像我们生活中的火车一样,乘客就如同数据,火车往返运送乘客。
有些小伙伴可能不太清楚什么叫通道?什么叫缓冲区?下面我们来理解一下通道和缓冲区
通道和缓冲区
Java NIO系统的核心在于:通道和缓冲区
。通道表示打开到IO设备(例如:文件、套接字)的连接。若需要使用NIO系统,需要获取用于连接IO设备的通道以及用于容纳数据的缓冲区。软后操作缓冲区,对数据进行处理。简而言之,Channel负责传输,Buffer负责存储。
下面我们重点来谈谈这两个东西
Buffer
缓冲区(Buffer)在Java NIO中负责数据的存取。缓冲区就是数组。用于存储不同数据类型的数据,根据数据类型的不同(boolean除外),提供了如下相应类型的缓冲区:
类型 | 含义 |
---|---|
ByteBuffer | 字节缓冲区 |
CharBuffer | 字符缓存区 |
ShortBuffer | 短整型缓冲区 |
IntBuffer | 整型缓冲区 |
LongBuffer | 长整型缓冲区 |
FloatBuffer | 单精度浮点型缓冲区 |
DoubleBuffer | 双精度浮点型缓冲区 |
上述缓冲区的管理方式几乎一致,通过allocate()获取缓冲区。
缓冲区获取数据的核心方法:
方法 | 解析 |
---|---|
put() | 存入数据到缓冲区中 |
get() | 获取缓冲区中的数据 |
flip() | 切换到读数据模式 |
rewind() | 可重复读数据 |
clear() | 清空缓冲区数据 |
hasRemaining() | 缓冲区中是否还有可以操作的数据 |
remaining() | 查看缓冲区中剩余可操作数的大小 |
缓冲区中的四个核心属性:
属性 | 解析 |
---|---|
capacity | 容量,表示缓冲区中最大存储数据的容量,一旦声明不能改变 |
limit | 界限,表示缓冲区中可以操作数据的大小。(limit后数据不能进行读写) |
position | 位置,表示缓冲区中正在操作数据的位置 |
mark | 标记,表示记录当前Position的位置,可以通过reset()恢复到mark的位置 |
下面我们看一下代码
1 @Test
2 public void test1() {
3 // 分配一个指定大小的缓冲区
4 ByteBuffer buf = ByteBuffer.allocate(10);
5 System.out.println(buf.capacity());
6 System.out.println(buf.limit());
7 System.out.println(buf.position());
8 }/*Output:
9 10
10 10
11 0
12 *///~
图解:
我们现在尝试在缓冲区中添加数据
1 @Test
2 public void test1() {
3 // 分配一个指定大小的缓冲区
4 ByteBuffer buf = ByteBuffer.allocate(10);
5 System.out.println(buf.capacity());
6 System.out.println(buf.limit());
7 System.out.println(buf.position());
8
9 System.out.println("添加数据");
10 String data = "11111";
11 buf.put(data.getBytes());
12 System.out.println(buf.capacity());
13 System.out.println(buf.limit());
14 System.out.println(buf.position());
15 }/*Output:
16 10
17 10
18 0
19 添加数据
20 10
21 10
22 5
23 *///~
图解:
在缓冲区读取数据:
1 @Test
2 public void test1() {
3 // 分配一个指定大小的缓冲区
4 ByteBuffer buf = ByteBuffer.allocate(10);
5 System.out.println(buf.capacity());
6 System.out.println(buf.limit());
7 System.out.println(buf.position());
8
9 System.out.println("添加数据");
10 String data = "11111";
11 buf.put(data.getBytes());
12 System.out.println(buf.capacity());
13 System.out.println(buf.limit());
14 System.out.println(buf.position());
15
16 System.out.println("flip-->切换到读数据模式");
17 buf.flip();
18 System.out.println(buf.capacity());
19 System.out.println(buf.limit());
20 System.out.println(buf.position());
21
22 }/*Output:
23 10
24 10
25 0
26 添加数据
27 10
28 10
29 5
30 flip
31 10
32 5
33 0
34 ×///~
35
图解:
通过这些例子,可以大概知道这几个属性的关系了吧!