1.什么是NIO & 什么是BIO?
BIO 指的是 Blocking I/O 从字面意思可以看出是阻塞IO , 他面向流,众所周知流是单向的所以他是同步阻塞IO
NIO指的是non - Bloking I/O 从字面意思可以看出事非阻塞IO, 它面向Buffer channel, Buffer 类似于缓存 所以他是同步非阻塞IO
2.什么是同步 & 异步
同步:指的是等待例如你去打印照片流程是:先付钱,然后拍照,然后等拿着照片,然后走,这是一个完整的流程,每一步都在等上一步返回才能执行这就是同步.
异步:指的是无需等待.还是照片例子我们都用过支付宝我打电话通知照相馆说我给你支付宝转了钱,电子照片也发你邮箱了,你打印出来后通知我我去拿,这样的话我就不需要每一次都等待,老板去打印他的照片,而我可以去打两局LoL然后老板就通知我来拿吧!我就去拿了.
总体来说同步与异步的区别就是等不等的区别通知与不通知的区别.
3.为什么不使用BIO?
这个问题 我只能回答:跟风!人家用什么我就用什么........(ex:当然不可能)
众所周知BIO需要单独起线程去接收,如果线程多了可能导致服务器繁忙而无法及时响应用户请求造成很差的用户体验.
4.QC
先上一个BIO例子!
一个常规的读文件操作:
System.out.println(Thread.currentThread().getContextClassLoader().getResource("test.txt").getPath());
InputStream inpupStream = new FileInputStream(new File(Thread.currentThread().getContextClassLoader().getResource("test.txt").getPath()));
BufferedReader bf = new BufferedReader(new InputStreamReader(inpupStream));
System.out.println(bf.readLine());
System.out.println(bf.readLine());
System.out.println(bf.readLine());
System.out.println(bf.readLine());
当然 和你想的一样我在resources下面建立了文件test.txt 文件内容如下
age:23
name:liuyang
work:developer
address:lk
当我运行这个方法他的打印结果 你也应该知道了:
/H:/mytest/iodemo/target/classes/test.txt
age:23
name:liuyang
work:developer
address:lk
以上就是一个BIO的简单操作!
好的NIO开始了! (我会联通compact一起介绍)
直接上代码:
public class CompactDemo {
private static String value = "Hello";
public static void main(String[] args) {
//定义容量
CharBuffer charBuffer = CharBuffer.allocate(6);
for (char oneChar : value.toCharArray()) {
charBuffer.put(oneChar);
}
System.out.println("数据准备完毕目前各个状态 limit为" + charBuffer.limit() + "position为" + charBuffer.position() + "mark为" + charBuffer.mark() + "capacity为" + charBuffer.capacity());
//开始读模式!
charBuffer.flip();
//读两个char
for (int index = 0; index < 2; index++) {
System.out.println(charBuffer.get());
}
System.out.println("数据取用完毕目前各个状态 limit为" + charBuffer.limit() + "position为" + charBuffer.position() + "mark为" + charBuffer.mark() + "capacity为" + charBuffer.capacity());
//复写重置状态
charBuffer.compact();
System.out.println("数据丢弃完毕目前各个状态 limit为" + charBuffer.limit() + "position为" + charBuffer.position() + "mark为" + charBuffer.mark() + "capacity为" + charBuffer.capacity());
}
}
我们理解下各个buffer各个标志位的作用!
mark : 他只是一个标志位不初始化
position:当前位置
limit:最大位置
capacity:容量不可变
写时position向后移动直到limit或者可以说是capacity,读时也就是flip,他会改变指针位置position 移动到第一个可以被读取的位置limit移动到以前position位置 这个在javaNio 一书有图大家可以看下.
当compact时 会丢弃已经读的数据然后将未读数据向前移动直到第一个字符位置然后就像与位置复用不保留已读位置.这样就算是个覆盖了已读数据.
好直接上结果注释我也写了可以参考下:
数据准备完毕目前各个状态 limit为6position为5mark为 capacity为6
H
e
数据取用完毕目前各个状态 limit为5position为2mark为llocapacity为6
数据丢弃完毕目前各个状态 limit为6position为3mark为lo capacity为6
好的我还在学习一起学习吧如有不对请指正多谢!