IO(BIO) 和NIO 的区别:其本质就是阻塞和非阻塞的区别
阻塞概念:应用程序在获取网络数据的时候,如果网络传输数据很慢,那么程序就一直等着,直到传输完毕为止。
非阻塞概念:应用程序直接可以获取已经准备就绪好的数,无需等待。(会将数据放在缓存区,加载完后 会给客户端发送一个信号,客户端会读取数据)
IO为同步阻塞模式,NIO为同步非阻塞模式,NIO并没有实现异步,而JDK1.7以后AIO 支持异步。
同步时,应用程序会直接参与IO读写操作,并且我们的应用程序会直接阻塞到某一个方法上,直到数据准备就绪;或者采用轮询的策略实时检查数据的就绪状态,如果就绪则获取数据
异步时,则所有的IO读写操作交给操作系统处理,与我们的应用程序没有直接关系,我们程序不需要关系IO读写,当操作系统完成IO读写操作时,会给我们应用程序发送通知,我们的应用程序直接拿走数据即可。
java.io 最为核心的一个概念就是流,面向流的编程。在java中,一个流要么是输入流,要么是输出流,不可能同时既是输入流又是输出流。
Java.nio 中拥有3个核心概念:Selector ,Channel与Buffer。在java.nio中,我们是面向块或是缓冲区编程的。Buffer本身就是一块内存,底层实现上,就是个数组,数据的读写都是通过Buffer来实现的。
除了数组之外,Buffer还提供了对于数据的结构化访问方式,并且可以追踪到系统的读写过程。
java中的8中原生数据类型都有各自的Buffer类型,如IntBuffer,LongBuffer等等
Channel指的是可以向其写入数据或者是从中读取数据的对象,它类似于java.io中的Stream。
所有的数据的读写都是通过Buffer来进行的,永远不会出现直接向Channel写入数据的情况,或者从Channel读取数据的情况。
与Stream不同的是,Channel是双向的,一个流只可能是InputStream或者OutputStream,Channel大开后则可以进行读取 写入。
由于Channel是双向的,因此它能更好的反应出底层操作系统的真实情况,在Linux系统中,底层操作系统的通道就是双向的。
通道Channel,它就像自来水管道一样,网络数据通过channle读取和写入,通道与流不同之处在于通道是双向的,而流只是一个方向上移动的,而通道可以读写二者同时进行,最关键的是可以与多路复用器结合起来,有多种的状态位,方便多路复用器去识别。
通道分为两类 : 一类是网络读写的 SelectableChannel 一类事用于文件操作的FileChannel 我们使用SocketChannel和ServerSocketChannel都是SelectableChannel的子类
下面来个简单的栗子:
package nio;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class NioTest {
public static void main(String[] args) throws IOException{
FileInputStream fileInputStream = new FileInputStream("Niotest.txt");
FileChannel fileChannel =fileInputStream.getChannel();
ByteBuffer byteBuffer = ByteBuffer.allocate(512);
fileChannel.read(byteBuffer);
byteBuffer.flip();
while(byteBuffer.remaining()>0){
byte b = byteBuffer.get();
System.out.println("---:"+(char)b);
}
fileInputStream.close();
}
}
package nio;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class NioTest3 {
public static void main(String[] args) throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream("Niotest3.txt");
FileChannel fileChannel =fileOutputStream.getChannel();
ByteBuffer byteBuffer = ByteBuffer.allocate(512);
byte[] mess = " hello wrold welcome , nihao".getBytes();
for (int i = 0; i< mess.length;i++){
byteBuffer.put(mess[i]);
}
byteBuffer.flip();
fileChannel.write(byteBuffer);
fileOutputStream.close();
}
}
package nio;
import java.nio.IntBuffer;
import java.util.Random;
public class NioTest2 {
public static void main(String[] args) {
IntBuffer intBuffer = IntBuffer.allocate(10);
for (int i = 0; i <intBuffer.capacity() ; i++) {
int rand = new Random().nextInt(20);
intBuffer.put(rand);
}
intBuffer.flip();
while (intBuffer.hasRemaining()){
System.out.println(intBuffer.get());
}
}
}