自学内容网 自学内容网

Java IO 与 BIO、NIO、AIO 详解

在 Java 中,I/O(输入/输出)操作是与外部系统(如文件、网络等)进行数据交换的基础。Java 提供了多种 I/O 机制,包括传统的阻塞式 I/O(BIO)、非阻塞式 I/O(NIO)和异步 I/O(AIO)。本文将详细探讨这三种 I/O 模型的特点、区别及其适用场景。

1 BIO(Blocking I/O)

BIO 是一种同步阻塞 I/O 模型。在这种模型中,线程在执行 I/O 操作时会被阻塞,直到操作完成。BIO 适用于连接数较少且稳定的场景。

特点

  • 同步阻塞:线程在执行 I/O 操作时被阻塞,无法处理其他任务。
  • 简单易用:API 直观简单,易于理解和使用。
  • 性能较低:每个连接都需要一个单独的线程,适用于连接数较少的场景。

示例代码

public class BioFileDemo {
    public static void main(String[] args) {
        BioFileDemo demo = new BioFileDemo();
        demo.writeFile();
        demo.readFile();
    }

    // 使用 BIO 写入文件
    public void writeFile() {
        String filename = "logs/itwanger/paicoding.txt";
        try {
            FileWriter fileWriter = new FileWriter(filename);
            BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);

            bufferedWriter.write("学编程就上技术派");
            bufferedWriter.newLine();

            System.out.println("写入完成");
            bufferedWriter.close();
            fileWriter.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 使用 BIO 读取文件
    public void readFile() {
        String filename = "logs/itwanger/paicoding.txt";
        try {
            FileReader fileReader = new FileReader(filename);
            BufferedReader bufferedReader = new BufferedReader(fileReader);

            String line;
            while ((line = bufferedReader.readLine()) != null) {
                System.out.println("读取的内容: " + line);
            }

            bufferedReader.close();
            fileReader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

2 NIO(New I/O 或 Non-blocking I/O)

NIO 是一种同步非阻塞 I/O 模型。在这种模型中,线程在等待 I/O 时可以执行其他任务,通过 Selector 监控多个 Channel 上的事件,提高性能和可伸缩性。NIO 适用于高并发场景。

特点

  • 同步非阻塞:线程在等待 I/O 时可执行其他任务。
  • I/O 多路复用:通过 Selector 监控多个 Channel 上的事件。
  • 性能较高:单个线程可以处理多个连接,适用于高并发场景。

示例代码

public class NioFileDemo {
    public static void main(String[] args) {
        NioFileDemo demo = new NioFileDemo();
        demo.writeFile();
        demo.readFile();
    }

    // 使用 NIO 写入文件
    public void writeFile() {
        Path path = Paths.get("logs/itwanger/paicoding.txt");
        try {
            FileChannel fileChannel = FileChannel.open(path, EnumSet.of(StandardOpenOption.CREATE, StandardOpenOption.WRITE));

            ByteBuffer buffer = StandardCharsets.UTF_8.encode("学编程就上技术派");
            fileChannel.write(buffer);

            System.out.println("写入完成");
            fileChannel.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 使用 NIO 读取文件
    public void readFile() {
        Path path = Paths.get("logs/itwanger/paicoding.txt");
        try {
            FileChannel fileChannel = FileChannel.open(path, StandardOpenOption.READ);
            ByteBuffer buffer = ByteBuffer.allocate(1024);

            int bytesRead = fileChannel.read(buffer);
            while (bytesRead != -1) {
                buffer.flip();
                System.out.println("读取的内容: " + StandardCharsets.UTF_8.decode(buffer));
                buffer.clear();
                bytesRead = fileChannel.read(buffer);
            }

            fileChannel.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

3 AIO(Asynchronous I/O)

AIO 是一种异步非阻塞 I/O 模型。在这种模型中,线程发起 I/O 请求后立即返回,当 I/O 操作完成时通过回调函数通知线程。AIO 进一步提高了并发处理能力,适用于高吞吐量场景。

特点

  • 异步非阻塞:线程发起 I/O 请求后立即返回,通过回调函数处理结果。
  • 高性能:适用于高吞吐量场景,充分利用操作系统参与并发操作。
  • 复杂性较高:编程复杂度较高,需要处理回调函数。

示例代码

public class AioDemo {
    public static void main(String[] args) {
        AioDemo demo = new AioDemo();
        demo.writeFile();
        demo.readFile();
    }

    // 使用 AsynchronousFileChannel 写入文件
    public void writeFile() {
        Path path = Paths.get("logs/itwanger/paicoding.txt");
        try {
            AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.WRITE, StandardOpenOption.CREATE);

            ByteBuffer buffer = StandardCharsets.UTF_8.encode("学编程就上技术派");
            Future<Integer> result = fileChannel.write(buffer, 0);
            result.get();

            System.out.println("写入完成");
            fileChannel.close();
        } catch (IOException | InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }

    // 使用 AsynchronousFileChannel 读取文件
    public void readFile() {
        Path path = Paths.get("logs/itwanger/paicoding.txt");
        try {
            AsynchronousFileChannel fileChannel = AsynchronousFileChannel.open(path, StandardOpenOption.READ);
            ByteBuffer buffer = ByteBuffer.allocate(1024);

            fileChannel.read(buffer, 0, buffer, new CompletionHandler<Integer, ByteBuffer>() {
                @Override
                public void completed(Integer result, ByteBuffer attachment) {
                    attachment.flip();
                    System.out.println("读取的内容: " + StandardCharsets.UTF_8.decode(attachment));
                    attachment.clear();
                    try {
                        fileChannel.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void failed(Throwable exc, ByteBuffer attachment) {
                    System.out.println("读取失败");
                    exc.printStackTrace();
                }
            });

            Thread.sleep(1000);
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }
}

4 三种 I/O 模型的区别

模型同步/异步阻塞/非阻塞适用场景
BIO同步阻塞连接数较少且稳定的场景
NIO同步非阻塞高并发场景 (即连接数目多且连接比较短的场景)
AIO异步非阻塞高吞吐量场景 (即连接数目多且连接比较长的场景)

5 总结

  • BIO:采用阻塞式 I/O 模型,线程在执行 I/O 操作时被阻塞,无法处理其他任务,适用于连接数较少且稳定的场景。
  • NIO:使用非阻塞 I/O 模型,线程在等待 I/O 时可执行其他任务,通过 Selector 监控多个 Channel 上的事件,提高性能和可伸缩性,适用于高并发场景。
  • AIO:采用异步 I/O 模型,线程发起 I/O 请求后立即返回,当 I/O 操作完成时通过回调函数通知线程,进一步提高了并发处理能力,适用于高吞吐量场景。

理解这三种 I/O 模型的特点和适用场景,有助于在实际开发中选择合适的 I/O 机制,以提高程序的性能和可扩展性。

6 思维导图

在这里插入图片描述

7 参考链接

一文彻底解释清楚Java 中的NIO、BIO和AIO


原文地址:https://blog.csdn.net/gaosw0521/article/details/143798608

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!