千家信息网

Java中BIO、NIO和AIO的区别是什么

发表于:2025-01-16 作者:千家信息网编辑
千家信息网最后更新 2025年01月16日,这篇文章主要讲解了"Java中BIO、NIO和AIO的区别是什么",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Java中BIO、NIO和AIO的区别是
千家信息网最后更新 2025年01月16日Java中BIO、NIO和AIO的区别是什么

这篇文章主要讲解了"Java中BIO、NIO和AIO的区别是什么",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Java中BIO、NIO和AIO的区别是什么"吧!

IO

什么是IO? 它是指计算机与外部世界或者一个程序与计算机的其余部分的之间的接口。它对于任何计算机系统都非常关键,因而所有 I/O 的主体实际上是内置在操作系统中的。单独的程序一般是让系统为它们完成大部分的工作。

在 Java 编程中,直到最近一直使用 流 的方式完成 I/O。所有 I/O 都被视为单个的字节的移动,通过一个称为 Stream 的对象一次移动一个字节。流 I/O 用于与外部世界接触。它也在内部使用,用于将对象转换为字节,然后再转换回对象。

BIO

Java BIO即Block I/O , 同步并阻塞的IO。

BIO就是传统的java.io包下面的代码实现。

NIO

什么是NIO? NIO 与原来的 I/O 有同样的作用和目的, 他们之间最重要的区别是数据打包和传输的方式。原来的 I/O 以流的方式处理数据,而 NIO 以块的方式处理数据。

面向流 的 I/O 系统一次一个字节地处理数据。一个输入流产生一个字节的数据,一个输出流消费一个字节的数据。为流式数据创建过滤器非常容易。链接几个过滤器,以便每个过滤器只负责单个复杂处理机制的一部分,这样也是相对简单的。不利的一面是,面向流的 I/O 通常相当慢。

一个 面向块 的 I/O 系统以块的形式处理数据。每一个操作都在一步中产生或者消费一个数据块。按块处理数据比按(流式的)字节处理数据要快得多。但是面向块的 I/O 缺少一些面向流的 I/O 所具有的优雅性和简单性。

AIO

Java AIO即Async非阻塞,是异步非阻塞的IO。

区别及联系

  • BIO (Blocking I/O):同步阻塞I/O模式,数据的读取写入必须阻塞在一个线程内等待其完成。这里假设一个烧开水的场景,有一排水壶在烧开水,BIO的工作模式就是, 叫一个线程停留在一个水壶那,直到这个水壶烧开,才去处理下一个水壶。但是实际上线程在等待水壶烧开的时间段什么都没有做。

  • NIO (New I/O):同时支持阻塞与非阻塞模式,但这里我们以其同步非阻塞I/O模式来说明,那么什么叫做同步非阻塞?如果还拿烧开水来说,NIO的做法是叫一个线程不断的轮询每个水壶的状态,看看是否有水壶的状态发生了改变,从而进行下一步的操作。

  • AIO ( Asynchronous I/O):异步非阻塞I/O模型。异步非阻塞与同步非阻塞的区别在哪里?异步非阻塞无需一个线程去轮询所有IO操作的状态改变,在相应的状态改变后,系统会通知对应的线程来处理。对应到烧开水中就是,为每个水壶上面装了一个开关,水烧开之后,水壶会自动通知我水烧开了。

各自适用场景

  • BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4以前的唯一选择,但程序直观简单易理解。

  • NIO方式适用于连接数目多且连接比较短(轻操作)的架构,比如聊天服务器,并发局限于应用中,编程比较复杂,JDK1.4开始支持。

  • AIO方式适用于连接数目多且连接比较长(重操作)的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂,JDK7开始支持。

使用方式

使用BIO实现文件的读取和写入。

        //Initializes The Object        User1 user = new User1();        user.setName("hollis");        user.setAge(23);        System.out.println(user);         //Write Obj to File        ObjectOutputStream oos = null;        try {            oos = new ObjectOutputStream(new FileOutputStream("tempFile"));            oos.writeObject(user);        } catch (IOException e) {            e.printStackTrace();        } finally {            IOUtils.closeQuietly(oos);        }         //Read Obj from File        File file = new File("tempFile");        ObjectInputStream ois = null;        try {            ois = new ObjectInputStream(new FileInputStream(file));            User1 newUser = (User1) ois.readObject();            System.out.println(newUser);        } catch (IOException e) {            e.printStackTrace();        } catch (ClassNotFoundException e) {            e.printStackTrace();        } finally {            IOUtils.closeQuietly(ois);            try {                FileUtils.forceDelete(file);            } catch (IOException e) {                e.printStackTrace();            }        }        //Initializes The Object        User1 user = new User1();        user.setName("hollis");        user.setAge(23);        System.out.println(user);         //Write Obj to File        ObjectOutputStream oos = null;        try {            oos = new ObjectOutputStream(new FileOutputStream("tempFile"));            oos.writeObject(user);        } catch (IOException e) {            e.printStackTrace();        } finally {            IOUtils.closeQuietly(oos);        }         //Read Obj from File        File file = new File("tempFile");        ObjectInputStream ois = null;        try {            ois = new ObjectInputStream(new FileInputStream(file));            User1 newUser = (User1) ois.readObject();            System.out.println(newUser);        } catch (IOException e) {            e.printStackTrace();        } catch (ClassNotFoundException e) {            e.printStackTrace();        } finally {            IOUtils.closeQuietly(ois);            try {                FileUtils.forceDelete(file);            } catch (IOException e) {                e.printStackTrace();            }        }

使用NIO实现文件的读取和写入。

 static void readNIO() {                String pathname = "C:\\Users\\adew\\Desktop\\jd-gui.cfg";                FileInputStream fin = null;                try {                        fin = new FileInputStream(new File(pathname));                        FileChannel channel = fin.getChannel();                         int capacity = 100;// 字节                        ByteBuffer bf = ByteBuffer.allocate(capacity);                        System.out.println("限制是:" + bf.limit() + "容量是:" + bf.capacity()                                        + "位置是:" + bf.position());                        int length = -1;                         while ((length = channel.read(bf)) != -1) {                                 /*                                 * 注意,读取后,将位置置为0,将limit置为容量, 以备下次读入到字节缓冲中,从0开始存储                                 */                                bf.clear();                                byte[] bytes = bf.array();                                System.out.write(bytes, 0, length);                                System.out.println();                                 System.out.println("限制是:" + bf.limit() + "容量是:" + bf.capacity()                                                + "位置是:" + bf.position());                         }                         channel.close();                 } catch (FileNotFoundException e) {                        e.printStackTrace();                } catch (IOException e) {                        e.printStackTrace();                } finally {                        if (fin != null) {                                try {                                        fin.close();                                } catch (IOException e) {                                        e.printStackTrace();                                }                        }                }        }         static void writeNIO() {                String filename = "out.txt";                FileOutputStream fos = null;                try {                         fos = new FileOutputStream(new File(filename));                        FileChannel channel = fos.getChannel();                        ByteBuffer src = Charset.forName("utf8").encode("你好你好你好你好你好");                        // 字节缓冲的容量和limit会随着数据长度变化,不是固定不变的                        System.out.println("初始化容量和limit:" + src.capacity() + ","                                        + src.limit());                        int length = 0;                         while ((length = channel.write(src)) != 0) {                                /*                                 * 注意,这里不需要clear,将缓冲中的数据写入到通道中后 第二次接着上一次的顺序往下读                                 */                                System.out.println("写入长度:" + length);                        }                 } catch (FileNotFoundException e) {                        e.printStackTrace();                } catch (IOException e) {                        e.printStackTrace();                } finally {                        if (fos != null) {                                try {                                        fos.close();                                } catch (IOException e) {                                        e.printStackTrace();                                }                        }                }        }

使用AIO实现文件的读取和写入

public class ReadFromFile {  public static void main(String[] args) throws Exception {    Path file = Paths.get("/usr/a.txt");    AsynchronousFileChannel channel = AsynchronousFileChannel.open(file);     ByteBuffer buffer = ByteBuffer.allocate(100_000);    Future result = channel.read(buffer, 0);     while (!result.isDone()) {      ProfitCalculator.calculateTax();    }    Integer bytesRead = result.get();    System.out.println("Bytes read [" + bytesRead + "]");  }}class ProfitCalculator {  public ProfitCalculator() {  }  public static void calculateTax() {  }} public class WriteToFile {   public static void main(String[] args) throws Exception {    AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(        Paths.get("/asynchronous.txt"), StandardOpenOption.READ,        StandardOpenOption.WRITE, StandardOpenOption.CREATE);    CompletionHandler handler = new CompletionHandler() {       @Override      public void completed(Integer result, Object attachment) {        System.out.println("Attachment: " + attachment + " " + result            + " bytes written");        System.out.println("CompletionHandler Thread ID: "            + Thread.currentThread().getId());      }       @Override      public void failed(Throwable e, Object attachment) {        System.err.println("Attachment: " + attachment + " failed with:");        e.printStackTrace();      }    };     System.out.println("Main Thread ID: " + Thread.currentThread().getId());    fileChannel.write(ByteBuffer.wrap("Sample".getBytes()), 0, "First Write",        handler);    fileChannel.write(ByteBuffer.wrap("Box".getBytes()), 0, "Second Write",        handler);   }}

感谢各位的阅读,以上就是"Java中BIO、NIO和AIO的区别是什么"的内容了,经过本文的学习后,相信大家对Java中BIO、NIO和AIO的区别是什么这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

数据 阻塞 字节 方式 水壶 处理 系统 线程 你好 容量 同步 就是 模式 状态 复杂 于连 位置 对象 数目 文件 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 飞算云智自动软件开发 国家网络安全局监管支队 太原标准机架服务器厂家供应 表里查不到数据库的数据库 我的世界升级服务器教程 如何用数据库视图做统计 小学校园网络安全资料 思腾合力服务器质量 达梦数据库为员工提供住宿吗 数据库相关面试 对数据库技术与应用这本书的理解 河北区有哪些服务器云主机 蓬莱商城软件开发公司 汽车行业软件开发公司排名 给数据库改名字sql 好人好事日记软件开发 没有输入网络安全钥匙界面 期货平台 期货软件开发 中奥服务器类型 数据库查询表怎么设置分数段 金蝶破解版安装后没有服务器 网络技术单招专业技能考试考什么 手机关机了怎么知道还在服务器 杭州新新网络技术 浅谈无线网络安全策略 职校软件开发 深圳软件开发公司联系电话 安全连接服务器地址怎么设置 希溥深圳网络技术有限公司 激光打标软件开发
0