IO/NIO — NIO

相比于之前讲的输入流、输出流、缓冲流等传统IO,jdk1.4提供的NIO在效率上会更高,jdk1.7时,提供了Files工具类,支持异步Channel的IO,效率更高

区别:IO面向流,NIO面向缓冲区

一、相关概念
1、阻塞和非阻塞
  • 阻塞:线程访问资源时,资源未准备好,持续等待
  • 非阻塞:线程访问资源时,资源未准备好,直接相应,不会等待
2、同步和异步
  • 同步:访问数据时,主动请求并等待IO操作完成
  • 异步:访问数据时,请求后可以继续处理其他任务
3、IO模型
  • 传统BIO模型

    同步阻塞,IO在执行读写时,线程被阻塞,等待读写完成

  • 伪异步IO模型

    和同步阻塞类似,加入了线程池维护IO现在,效率相对BIO更高

  • NIO模型

    是一种同步非阻塞IO,面向缓冲区进行操作,单个线程通过Selector(多路复用器)监听多个通道事件,实现高效

二、NIO的使用
1、NIO优点
  • 通过注册ChannelSelector上的状态来实现客户端与服务端的通信
  • Channel中数据的读取是通过Buffer,是一种非阻塞的读取方式(轮询看数据准备好没)
  • Selector多路复用器,单线程,线程资源开销小
2、Channel(通道)

区别于IO中读取数据时,会发生阻塞等待数据,NIO的Channel对象可以通过不同的阻塞行为,判断进行相应的操作,实现非阻塞通道

Channel`是双向的,可以读也可以写

  • Channel接口的相关实现类

    FileChannel:支持文件操作

    Pipe.SinkChannelPipe.SourceChannel:支持线程间通信

    ServerSocketChannel:支持TCP网络通信

    DategramChannel:支持UDP网络通信

  • 创建方法:

    根据流节点(如InputStreamOutputStream)的getChannel()方法来返回对应的 Channel(如FileChannel等)

  • 常用方法:

    map():用于将 Channel 对应的部分或全部数据映射成ByteBuffer

    read():从 Buffer 读入数据

    write():从 Buffer 写入数据

3、Buffer(缓冲区)

是一个缓冲区,也是一个容器,像一个数组,可以保存多个同类型数据在Channel读写数据时,中间需要经过Buffer

Buffer的使用

  • 3个重要概念:

    容量(capacity):Buffer的最大数据容量,创建后不能改变

    界限(limit):位于limit后的区域,不能被读写

    位置(position):指明下一个被读或者被写入的位置索引

  • 当 Buffer 装入数据结束,调用flip()方法,让指针复位,即上图已经读写区域清除,为输出数据做准备
  • 当 Buffer 输出数据结束,调用clear()方法,将整个区域设为尚未读写区域,为再次向 Buffer 中装入数据做准备(数据并未清除)
4、Selector(多路复用器)

和 Channel 相互配合使用,可以监听 Channel 的四种状态,监听到对应的状态时,才允许对 Channel进行相应的操作

  • Read:可读

  • Write:可写

  • Connect:客户端连接成功

  • Accept:准备好进行连接

5、使用示例

读取文件

public static void main(String[] args) throws IOException{
    File fiel = new File("test.txt");
    // 创建一个文件输入流,并获得文件输入流对应的管道
    FileChannel inChannel = new FileInputStream(file).getChannel();
    // 创建一个字节缓冲区(Channel的读取都要通过缓冲区完成)
    ByteBuffer buf = ByteBuffer.allocate(1024);
    // 将数据写入缓冲区
    int readCount = inChannel.read(buf);
    while((fileChannel.read(buf)) > -1){
        // 装入数据完成,让指针复位,为输出数据做准备
        buf.flip();
        while(bug.hasRemaining()){
            // 打印
            System.out.print((char)buf.get())
        }
        // 清除缓冲区之前数据,复位标记位为0,配合 filp()使用
        buf.compact();
    }
}
三、jdk1.7的 NIO(改进)

提供了全面的文件IO和文件系统访问

基于异步Channel的IO

1、 Path、Paths和Files工具类
  • Path:该接口代表一个与平台无关的平台路径
  • Paths:获取Path对象
  • Files:操作文件的工具类
2、Files工具类常用方法
  • readAllBytes(Path p):获取文件内容(byte)

    该方法可以和String(byte[] b, String utf-f)一起使用,转字符串

  • write(Path p, String):将 String 写入到 p 文件中

  • copy(Path p, OutputStream out):将p文件内容复制到输出流 out 的文件中(源码里调了copy(in, out),一个输入流,一个输出流)

  • delete(Path p):将 p 文件删除

3、使用示例

获取文件内容

public static void main(String[] args){
    // 文件路径
    Path p = Paths.get("test.txt");
    // 读取 test.txt 文件的内容,放到 byte数组中
    byte[] byt = Files.readAllBytes(p);
    // 将字节数组转字符串并打印
    System.out.print(new String(byt, "utf8"));
}

文件复制

public static void main(String[] args){
    // 文件路径
    Path p = Paths.get("test.txt");
    // 字符输出流
    FileOutputStream out = new FileOutputStream("newTest.txt");
    // 将 test.txt 复制到 newTest.txt
    Files.copy(p, out);
}
### 回答1: IO(输入输出)是指操作系统与硬件之间进行数据传输的过程。常见的IO操作包括读取和写入文件、网络数据传输等。 NIO (非阻塞IO)是Java中的一种IO编程方式,它支持非阻塞的数据传输,即程序在等待IO操作完成时不会阻塞。这样可以避免程序因等待IO而卡住的问题。NIO提供了异步通道、缓冲区等功能来支持高效的IO操作。 AIO (异步IO)是操作系统提供的另一种IO编程方式,它支持异步的数据传输。AIO允许程序在发起IO请求后立即返回,而不是等待IO操作完成。这样程序可以继续执行其他任务,避免因等待IO而阻塞。AIO在操作系统层面支持异步IO,而NIO是在Java语言层面支持异步IO. ### 回答2: IO,即Input/Output,是指计算机与外部设备之间进行数据传输的过程。传统的IO操作是同步的,即在进行IO操作时,程序会阻塞等待数据的读写完成。这种方式效率较低,因为程序在等待IO操作完成时无法做其他事情。 NIO,即New Input/Output,是Java在JDK1.4版本引入的一种新的IO模型NIO可以实现非阻塞的IO操作,其核心是通过通道(Channel)和缓冲区(Buffer)来实现数据的读写。NIO通过选择器(Selector)实现了多路复用,一个线程可以同时处理多个通道的IO操作,实现了更高的效率。NIO适用于连接数较多且连接时间较短的场景,例如网络编程中的ServerSocketChannel和SocketChannel。 AIO,即Asynchronous Input/Output,是Java在JDK1.7版本引入的一种新的IO模型。AIO通过回调机制实现异步的IO操作,当IO操作完成后会触发回调函数的执行。AIO适用于连接数较少且连接时间较长的场景,例如网络编程中的AsynchronousServerSocketChannel和AsynchronousSocketChannel。相比于NIO,AIO的优势是在IO操作完成前不需要阻塞线程,可以充分利用线程资源,并且编程模型更简单。 综上所述,IO是传统的同步IO模型,效率较低;NIO是一种非阻塞的IO模型,通过选择器实现了多路复用,效率较高;AIO是一种异步的IO模型,通过回调机制实现了非阻塞的IO操作,适用于连接时间较长的场景。在实际开发中,可以根据具体需求选择适合的IO模型来提高程序的性能和效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值