0
点赞
收藏
分享

微信扫一扫

NIO、AIO概述总结

晚安大世界 2022-04-16 阅读 112
java

        经过前几天的学习,将BIO的基础知识总结完成,接下来今天我将总结学习NIO和AIO的知识点,在理解学习的基础上,去使用相关知识点进行编程学习。这次我将先总结NIO的知识点,再学习AIO的相关概念。

NIO

NIO主要有三大核心部分:Channel(通道),Buffer(缓冲区), Selector。传统IO基于字节流和字符流进行操作,而NIO基于Channel和Buffer(缓冲区)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。Selector(选择区)用于监听多个通道的事件(比如:连接打开,数据到达)。因此,单个线程可以监听多个数据通道。 

NIO是采用内存映射文件的方式处理输出输出,可以将文件或者文件的一段区域映射到内存中,然后就可以像访问内存一样来访问文件,所以进行输入输出的速度比BIO快的多。

1.Channel

Channel可以直接将文件的部分或者全部映射到 buffer中。注意不能直接访问Channel中的数据,包括 读写都不行,Channel只能与buffer进行交互。

常见方法有3map/read/write

public class Test1 { 
    public static void main(String[] args) throws Exception { 
        File file = new File("data/Test1.java"); // 获取channel对象 
        FileChannel inChannel = new FileInputStream(file).getChannel(); 12345
        ByteBuffer buffer = ByteBuffer.allocate(256);// 构建一个容积为256的 buffer 
// 从channel中获取数据写到buffer中。文件可能大于256,所以需要进行多次读取。 可以通过-1判定读取结束 
        while (inChannel.read(buffer) != -1) { // 将buffer中没有数据的部分封印起来 
            buffer.flip(); // 设置limit,limit之后的数据不允许操作 
            System.out.println(buffer.limit()); //256 
            Charset charset = Charset.forName("UTF-8"); // 参数为编码字符集名 称,创建对应编码字符集的解码器 
            CharsetDecoder decoder = charset.newDecoder();//通过Charset创建对应的解码器对象  
            CharBuffer cb = decoder.decode(buffer);// 使用解码器可以将 ByteBuffer转换为   
            CharBuffer System.out.println(cb); 
            buffer.clear();// 清空buffer中的数据,同时将position设置为0,为下一次 读取操作做准备 
        } 
    } 
}

2. Buffer(缓冲区)

Buffer主要作用就是用于转入数据,然后输出数据。最基本的实现是ByteBuffer,可以在字节数组上进行 get/set操作;另外针对基本数据类型,系统提供了7种具体的实现,例如CharBuffer、ShortBuffer、 DoubleBuffer。 

3.Selector

是Java NIO核心组件中的一个,用于检查一个或多个NIO Channel通道的状态是否处于可读、可写。如 此可以实现单线程管理多个channels也就是可以管理多个网络链接。

使用Selector的好处在于: 使用更少的线程来就可以来处理通道了, 相比使用多个线程,避免了线程上下文切换带来的开销


AIO(异步非阻塞式 )

AIO最大的一个特性就是异步能力,这种能力对socket与文件I/O都起作用。AIO其实是一种在读写操作结束之前允许进行其他操作的I/O处理。

JDK7新增了一些和文件、网络IO相关的APIAIO最大的特性就是异步处理能力,一般用于网络编程和大文件IO处理中。AIO其实就是一种在读写操作结束之前允许执行其它操作的IO处理,等读写执行完毕自动通知调用后续处理。

1.将来式异步读取:使用Future用来保存异步操作的处理结果

Path path = Paths.get("data/a1.txt"); // 从语义的角度上说比File好一些,用于封装一个文件或者文件夹对象 
AsynchronousFileChannel channel = AsynchronousFileChannel.open(path, StandardOpenOption.READ); 

ByteBuffer buffer = ByteBuffer.allocate(1024); 
Future<Integer> future = channel.read(buffer, 0); 
int readNum = future.get(); 

buffer.flip(); 
CharBuffer cb = CharBuffer.allocate(1024); 
CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder(); 
decoder.decode(buffer,cb,false);

cb.flip(); 
String ss=new String(cb.array(),0,cb.limit()); 
System.out.println(ss);

2.回调式异步读取:回调式是采用事件处理技术实现的

Path path = Paths.get("data/a1.txt"); // 从语义的角度上说比File好一些,用于封装一个文件或者文件夹对象 
AsynchronousFileChannel channel = AsynchronousFileChannel.open(path, StandardOpenOption.READ); 
ByteBuffer buffer = ByteBuffer.allocate(1024); 
channel.read(buffer, 0, buffer, new CompletionHandler<Integer, ByteBuffer>() 
{ 
    // 当读取完成后自动执行的方法 
    public void completed(Integer result, ByteBuffer attachment) {         
        System.out.println(Thread.currentThread().getName() + "读取数据完毕!");
    }// 当读取处理过程中出错时自动执行的方法 
    public void failed(Throwable exc, ByteBuffer attachment) {     
        System.out.println(Thread.currentThread().getName() + "读取数据出现异 常:" + exc); 
    } 
}); 
System.out.println("立即看到结果!"); 
while (true) { 
    System.out.println(Thread.currentThread().getName() + "sleep...."); 
    Thread.sleep(1000); 
}

BIO、NIO、AIO总结

BIO:同步阻塞,实现模式为一个连接一个线程,就是客户端连接请求时,服务器需要启动一个线程进行处理。

NIO:同步非阻塞,实现模式为一个连接一个线程,客户端发起请求时会注册到selector多路复用器上,多路复用器会轮询所有有IO请求时才启动一个线程进行处理。

AIO:异步非阻塞,一个有效请求一个线程,客户端IO请求都是由OS操作系统先完成了再通知服务器应用启动线程进行处理。

        今天把NIO、AIO的相关知识点总结完成,最后又将BIO、NIO、AIO进行区别总结,流的基本知识就讲到了这里,期待更加深入的学习!同时对之前学过的知识再进行复习巩固,加强练习锻炼。加油!!!

举报

相关推荐

0 条评论