分散读取
分散读取(Scattering Reads)是指从Channel 中读取的数据“分散”到多个Buffer 中。
注意:按照缓冲区的顺序,从Channel 中读取的数据依次将 Buffer 填满。
聚集写入
聚集写入(Gathering Writes)是指将多个Buffer 中的数据“聚集”到Channel。
按照缓冲区的顺序,写入position 和limit 之间的数据到Channel。
代码语言:javascript复制import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class demo6 {
public static void main(String[] args) throws IOException {
FileInputStream is = new FileInputStream("");
FileOutputStream os = new FileOutputStream("");
FileChannel inChannel = is.getChannel();
FileChannel outChannel = os.getChannel();
// 获得多个缓冲区,并且放入到缓冲区数组中
ByteBuffer byteBuffer1 = ByteBuffer.allocate(50);
ByteBuffer byteBuffer2 = ByteBuffer.allocate(1024);
ByteBuffer[] byteBuffers = {byteBuffer1, byteBuffer2};
// 分散读取
inChannel.read(byteBuffers);
byteBuffer1.flip();
byteBuffer2.flip();
// 聚集写入
outChannel.write(byteBuffers);
}
}
非阻塞式网络通信
概念
比喻:
代码语言:javascript复制举个你去饭堂吃饭的例⼦,你好⽐⽤户程序,饭堂好⽐操作系统。
阻塞 I/O 好⽐,
你去饭堂吃饭,但是饭堂的菜还没做好,然后你就⼀直在那⾥等啊等,
等了好⻓⼀段时间终于等到饭堂阿姨把菜端了出来(数据准备的过程),
但是你还得继续等阿姨把菜(内核空间)打到你的饭盒⾥(⽤户空间),
经历完这两个过程,你才可以离开。
⾮阻塞 I/O 好⽐,
你去了饭堂,问阿姨菜做好了没有,阿姨告诉你没,
你就离开了,过⼏⼗分钟,你⼜来,
饭堂问阿姨,阿姨说做好了,于是阿姨帮你把菜打到你的饭盒⾥,这个过程你是得等待的。
基于⾮阻塞的 I/O 多路复⽤好⽐,
你去饭堂吃饭,发现有⼀排窗⼝,饭堂阿姨告诉你这些窗⼝都还没做好菜,
等做好了再通知你,于是等啊等( select 调⽤中),过了⼀会阿姨通知你菜做好了,
但是不知道哪个窗⼝的菜做好了,你⾃⼰看吧。
于是你只能⼀个⼀个窗⼝去确认,后⾯发现 5 号窗⼝菜做好了,
于是你让 5 号窗⼝的阿姨帮你打菜到饭盒⾥,这个打菜的过程你是要等待的,虽然时间不⻓。
打完菜后,你⾃然就可以离开了。
异步 I/O 好⽐,
你让饭堂阿姨将菜做好并把菜打到饭盒⾥后,把饭盒送到你⾯前,整个过程你都不需要任何等待。