Java IO(BIO、NIO、AIO)

本文深入探讨了Java中的IO操作,包括磁盘IO和网络IO。通过字节流和字符流展示了文件读写,并对比了同步阻塞IO(BIO)、非阻塞IO(NIO)和异步非阻塞IO(AIO)的区别。同时,解释了多路I/O复用的概念,如epoll模型,强调其如何提高处理高并发请求的效率。
摘要由CSDN通过智能技术生成

前言

程序中所有的数据都是以字节流的方式进行传输的,IO是指在主内存与外部设备(磁盘、网络)之间传输数据的过程,当外部设备还未准备就绪时就会出现IO阻塞。基于磁盘操作的 I/O 接口:File,基于网络操作的 I/O 接口:Socket

磁盘IO(文件读写)

// 字节操作的 I/O 接口:InputStream(读) 和 OutputStream(写)
BufferedInputStream bufferedInputStream = null;
BufferedOutputStream bufferedOutputStream = null;
try {
    // 字节输入流:读数据
    bufferedInputStream = new BufferedInputStream(
            new FileInputStream(new File("C:\\Users\\lixing\\Desktop\\通话录音.mp3")));
    // 字节输出流:写数据
    bufferedOutputStream = new BufferedOutputStream(
            new FileOutputStream(new File("C:\\Users\\lixing\\Desktop\\通话录音_.mp3")));
    // 复制文件
    byte[] readBytes = new byte[1024]; // 缓冲大小
    int readBytesLen; // 读取字节的长度
    while ((readBytesLen = bufferedInputStream.read(readBytes))!= -1) {
        bufferedOutputStream.write(readBytes, 0, readBytesLen);
    }
} catch (IOException e) {
    e.printStackTrace();
} finally {
    if (bufferedOutputStream != null) {
        try {
            bufferedOutputStream.close();
        } catch (IOException e) {
            System.out.println("bufferedOutputStream关闭失败");
        }
    }
    if (bufferedInputStream != null) {
        try {
            bufferedInputStream.close();
        } catch (IOException e) {
            System.out.println("bufferedInputStream关闭失败");
        }
    }
}
// 字符操作的 I/O 接口:Reader(读)和Writer(写) 
BufferedReader bufferedReader = null;
BufferedWriter bufferedWriter = null;
try {
    bufferedReader = new BufferedReader(new FileReader(new File("C:\\Users\\lixing\\Desktop\\demo.txt")));
    bufferedWriter = new BufferedWriter(new FileWriter(new File("C:\\Users\\lixing\\Desktop\\demo_.txt")));
    String readLine;
    while ( (readLine = bufferedReader.readLine()) != null) {
        bufferedWriter.write(readLine+"\r\n");
    }
} catch (IOException e) {
    e.printStackTrace();
} finally {
    if (bufferedWriter != null) {
        try {
            bufferedWriter.close();
        } catch (IOException e) {
            System.out.println("bufferedWriter关闭失败");
        }
    }
    if (bufferedReader != null) {
        try {
            bufferedReader.close();
        } catch (IOException e) {
            System.out.println("bufferedReader关闭失败");
        }
    }
}

网络IO(Socket)

网络 I/O 描述的是计算机之间完成相互通信一种抽象功能。实质是对 Socket 的读取,大部分情况下我们使用的都是基于 TCP/IP 的流套接字,它是一种稳定的通信协议。当客户端和服务端成功建立连接后都会拥有一个 Socket 实例,每个 Socket 实例都有一个 InputStream 和 OutputStream,正是通过这两个对象来交换数据的

同步、阻塞式IO(BIO)

客户端向服务器发起一个请求时,服务器就会为之创建一个线程来处理相关业务,当业务中涉及的IO资源还未准备就绪(即系统内核空间中的资源还未准备就绪),则当前线程将一直处于阻塞状态(导致用户空间阻塞),在高并发场景下,系统会因为创建大量的线程而消耗性能

小明(线程)去火车站买票,发现前面有100个人在排队(系统IO资源还未准备就绪),于是开始排队等待(线程处于阻塞状态),直到这100个人全部结束后再去买票
由于售票窗口的场地有限(系统内存有限),每来一个人就会为其分配一块空间(创建一个线程)去排队,当排队的人很多时(高并发场景),售票窗口的场地会越来越小(系统内存消耗的越来越多),最后场面一片混乱(系统处理请求的性能越来越弱)

同步、非阻塞式IO(NIO)

NIO默认采用的select poll模型,该模型会以轮询的方式去查看系统IO资源的就绪情况。自始至终,买票都是由小明亲操作的--同步

Java在1.5推出了NIO:
小明去火车站买票,发现前面有100个人在排队,于是便离开车站去做其它事情(非阻塞),以后每10分钟来车站查看排队情况(轮询系统IO资源的就绪情况),如果发现没有人排队了则去买票

异步、非阻塞式IO(AIO)

AIO默认采用的是epoll模型,该模型会将待处理的业务委托给操作系统做,操作系统处理好了后以回调的方式通知
买票是由小明发起的,但是不是由小明亲自买的--异步

Java1.7推出了AIO:
小明去车站买票,发现前面有100个人在排队,于是委托黄牛(操作系统)来帮他买票,自己便离开了车站去做其它事情(非阻塞),当黄牛买到票后便通知小明来取(回调通知)

多路 I/O 复用

这里“多路”指的是多个网络连接,“复用”指的是复用同一个线程,那顾名思义就是采用指单线程来处理多个网路的IO请求

多路 I/O 复用模型是利用epoll网络模型,可以同时监察多个流的 I/O 事件的能力,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有I/O事件时,就从阻塞状态中唤醒,于是程序就会轮询一遍所有的流(注意epoll只轮询那些真正发出了事件的流),并且依次有序的处理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大能嘚吧嘚

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值