NIO编程
NIO概述
什么是NIO?
Java NIO(New IO)是一个可以替代标准Java IO API的IO API(从Java 1.4开始),Java NIO提供了与标准IO不同的IO工作方式。
Java NIO: Channels and Buffers(通道和缓冲区)
标准的IO基于字节流和字符流进行操作的,
而NIO是基于通道(Channel)和缓冲区(Buffer)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。
Java NIO: Non-blocking IO(非阻塞IO)
Java NIO可以让你非阻塞的使用IO,
例如:当线程从通道读取数据到缓冲区时,线程还是可以进行其他事情。当数据被写入到缓冲区时,线程可以继续处理它。从缓冲区写入通道也类似。
Java NIO: Selectors(选择器)
Java NIO引入了选择器的概念,选择器用于监听多个通道的事件(比如:连接打开,数据到达)。因此,单个的线程可以监听多个数据通道。
注意:传统IO是单向的,而NIO是双向!
NIO双向:
IO与NIO的区别
IO | NIO |
---|---|
面向流 | 面向缓冲区 |
阻塞IO | 非阻塞IO |
无 | 选择器 |
Buffer的数据存取
一个用于特定基本数据类行的容器。有java.nio包定义的,所有缓冲区都是抽象类Buffer的子类。
Java NIO中的Buffer主要用于与NIO通道进行交互,数据是从通道读入到缓冲区,从缓冲区写入通道中的。
Buffer就像一个数组,可以保存多个相同类型的数据。根据类型不同(boolean除外),有以下Buffer常用子类:
ByteBuffer
CharBuffer
ShortBuffer
IntBuffer
LongBuffer
FloatBuffer
DoubleBuffer
Buffer的概述
1)容量(capacity):
表示Buffer最大数据容量,缓冲区容量不能为负,并且建立后不能修改。
2)限制(limit):
第一个不应该读取或者写入的数据的索引,即位于limit后的数据不可以读写。缓冲区的限制不能为负,并且不能大于其容量(capacity)。
3)位置(position):
缓冲区正在操作的位置)下一个要读取或写入的数据的索引。缓冲区的位置不能为负,并且不能大于其限制(limit)。
4)标记(mark)与重置(reset):
标记是一个索引,通过Buffer中的mark()方法指定Buffer中一个特定的position,之后可以通过调用reset()方法恢复到这个position。
总结
一、 (缓冲区)buffer 用于NIO存储数据 支持多种不同的数据类型
1.byteBuffer
2.charBuffer
3.shortBuffer
4.IntBuffer
5.LongBuffer
6.FloatBuffer
7.DubooBuffer
上述缓冲区管理的方式, 几乎通过allocate()获取缓冲区
二、缓冲区核心的方法
put 存入数据到缓冲区
get 获取缓冲区数据
flip 开启读模式
三、缓冲区四个核心属性
capacity:缓冲区最大容量,一旦声明不能改变。
limit:界面(缓冲区可以操作的数据大小) limit后面的数据不能读写。
position:缓冲区正在操作的位置
代码示例
public class BufferDemo {
public static void main(String[] args) {
System.out.println("---------制定缓冲区大小1024兆--------");
ByteBuffer allocate = ByteBuffer.allocate(1024);
System.out.println(allocate.position());
System.out.println(allocate.limit());
System.out.println(allocate.capacity());
allocate.put("WangYongSheng".getBytes());
System.out.println("---------向缓冲区存放13个数据--------");
System.out.println(allocate.position());
System.out.println(allocate.limit());
System.out.println(allocate.capacity());
System.out.println("---------开启读模式--------");
allocate.flip();
System.out.println(allocate.position());
System.out.println(allocate.limit());
System.out.println(allocate.capacity());
byte[] bytes = new byte[allocate.limit()];
allocate.get(bytes);
System.out.println(new String(bytes,0,bytes.length));
System.out.println("---------开启重读模式--------");
allocate.rewind();
System.out.println(allocate.position());
System.out.println(allocate.limit());
System.out.println(allocate.capacity());
byte[] bytes2=new byte[allocate.limit()];
allocate.get(bytes2);
System.out.println(new String(bytes2,0,bytes2.length));
System.out.println("---------清空缓冲区--------");
//clear 清空缓冲区 数据依然存在,只不过数据被遗忘
allocate.clear();
System.out.println(allocate.position());
System.out.println(allocate.limit());
System.out.println(allocate.capacity());
System.out.println((char)allocate.get());
}
}
运行结果
依次为: