IONIO — NIO

IONIO — NIO,第1张

IO/NIO — NIO

IO/NIO — NIO
        • 一、相关概念
          • 1、阻塞和非阻塞
          • 2、同步和异步
          • 3、IO模型
        • 二、NIO的使用
          • 1、NIO优点
          • 2、Channel(通道)
          • 3、Buffer(缓冲区)
          • 4、Selector(多路复用器)
          • 5、使用示例
        • 三、jdk1.7的 NIO(改进)
          • 1、 Path、Paths和Files工具类
          • 2、Files工具类常用方法
          • 3、使用示例

相比于之前讲的输入流、输出流、缓冲流等传统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优点
  • 通过注册Channel到Selector上的状态来实现客户端与服务端的通信
  • Channel中数据的读取是通过Buffer,是一种非阻塞的读取方式(轮询看数据准备好没)
  • Selector多路复用器,单线程,线程资源开销小
2、Channel(通道)

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

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

  • Channel接口的相关实现类

    FileChannel:支持文件 *** 作

    Pipe.SinkChannel、Pipe.SourceChannel:支持线程间通信

    ServerSocketChannel:支持TCP网络通信

    DategramChannel:支持UDP网络通信

  • 创建方法:

    根据流节点(如InputStream、OutputStream)的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);
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5482607.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-12
下一篇 2022-12-12

发表评论

登录后才能评论

评论列表(0条)

保存