面试记录之 Java 的 IO 和 NIO

记录一下什么是 IO 操作,什么操作是 NIO ,使用说明 api 去调用

一、概念

1.1 IO(Input/OutPut)

        在 Java 中使用 Java.io 包中的类实现了 I/O 模型。当应用程序发出 I/O 操作请求时,他会一直等待直到操作完成。在此期间无法执行其他操作。 Java 的大部分 IO 操作都是基于阻塞 IO 进行的。

1.2 NIO(New Input/OutPut)

        当应用程序发起一个 I/O 操作后,操作系统会立即返回,不会阻塞应用程序。应用程序需要不断地轮询操作系统,查询 I/O 操作是否已经完成。也是一种异步IO。 NIO 引入了非阻塞 IO 模式,提供了一套全新 API ,他将 IO 操作的结果封装成了时间,将事件通知给应用程序。NIO 还提供了选择器 ( Selector)等机制用于轮训 IO 事件并处理他。

        相比于阻塞 IO ,他更快;相比于 A IO,他更稳定。基于事件驱动模型,他分为了Channel、Buffer 和 Selector 三个概念

1.2.1 Channel (通道)

        类似于一个管道,是 NIO 和数据源通信的对象,可以进行读取、写入操作。也类似于流,但是他是可以双向传输的。

1.2.2 Buffer (缓冲区)

        是 NIO 用来储存数据的容器。可以读取和写入,类似于字节流。 NIO 的 Buffer 实现了 0拷贝,可以直接在哪丛中进行数据的复制和传输。

0拷贝:

        零拷贝主要是用来解决操作系统在处理 I/O 操作时,频繁复制数据的问题。关于零拷贝主要技术有 mmap+writesendfilesplice等几种方式。

缺点:

        不能操作文件了,因为都在底层处理了。因此还有一个中间方案 mmap 。

1.2.3 Selector(选择器)

        减少系统负载的组件。本来异步 IO 是要程序不断轮训查询结果。Selector 可以监听多个通道的 IO 事件,并且只有在有IO 事件发生时才会被唤醒,减少了系统的负载。IO 事件通常指输入/输出操作完成发出的通知。

NIO 和传统 IO 之间第一个最大的区别是,IO 是面向流的,NIO 是面向缓冲区的。

1.3 异步 I/O(Asynchronous I/O)

        非阻塞 IO 的升级版本。Java1.7 之后引入,提供了更简单易用的异步 IO 接口。Java 应用程序不需要等待 I/O 操作完成,而是在后台注册一个回调函数,在 I/O 操作完成后由内核自动回调这个函数,从而实现异步非阻塞 I/O。比如 AsynchronousChannel 和 AsynchronousSocketChannel 。

二、用法 

2.1 IO 

Java 的 io 包提供了一组用于读取和写入数据的类和接口,常用的类和接口包括:

  1. InputStream 和 OutputStream:字节流输入输出类,用于读取和写入字节数据。

  2. Reader 和 Writer:字符流输入输出类,用于读取和写入字符数据。

  3. File:表示文件或目录的类。

  4. RandomAccessFile:可随机访问的文件类,支持读取和写入文件任意位置的数据。

  5. BufferedInputStream 和 BufferedOutputStream:缓存字节流输入输出类,提高读取和写入效率。

  6. BufferedReader 和 BufferedWriter:缓存字符流输入输出类,提高读取和写入效率。

  7. DataInputStream 和 DataOutputStream:数据流输入输出类,支持读取和写入基本数据类型和字符串。

  8. ObjectInputStream 和 ObjectOutputStream:对象流输入输出类,支持读取和写入 Java 对象。

  9. InputStreamReader 和 OutputStreamWriter:字符流和字节流之间的转换类。

  10. PipedReader 和 PipedWriter:用于在线程之间传输数据的管道流类。

除了上述常用的类和接口,还有一些其他的类和接口,如 PushbackInputStream、FilterInputStream、SequenceInputStream 等。

2.2 NIO

Java NIO(New I/O)提供了新的 I/O 模型和 API,包括以下类和接口:

  1. Buffer:用于数据的读写缓冲区,包括 ByteBuffer、CharBuffer、DoubleBuffer、FloatBuffer、IntBuffer、LongBuffer、ShortBuffer 等。

  2. Channel:用于读写数据的通道,包括 FileChannel、DatagramChannel、SocketChannel、ServerSocketChannel 等。

  3. Selector:用于监控多个通道的状态,并且只会选择准备好进行 I/O 操作的通道进行读写操作。

  4. Charset:用于字符编码和解码的工具类。

  5. CharsetDecoder:用于将字节序列转换为字符序列。

  6. CharsetEncoder:用于将字符序列转换为字节序列。

  7. CompletionHandler:用于异步 I/O 操作完成后的回调。

  8. AsynchronousChannelGroup:用于管理异步通道的线程池。

  9. AsynchronousChannel:异步 I/O 通道的基类。

  10. AsynchronousSocketChannel:异步 Socket 通道。

  11. AsynchronousServerSocketChannel:异步 ServerSocket 通道。

  12. AsynchronousFileChannel:异步文件通道。

这些类和接口都是 Java NIO 中比较重要的组成部分。

三、总结

        IO 和 NIO 是 Java 中两种不同的 I/O 模型,其中 IO 使用阻塞 I/O,而 NIO 使用非阻塞 I/O。这两种模型有着不同的适用场景和优缺点。

        Java IO 包提供了文件读写、网络通信、序列化和反序列化等功能,但对于高并发的应用场景,IO 模型的效率比较低。Java NIO 是一种非阻塞 I/O 模型,其核心组件包括通道(Channel)、缓冲区(Buffer)和选择器(Selector)。NIO 可以使用一个线程来处理多个连接,实现高效的事件驱动模型。NIO 包提供了文件读写、网络通信和编解码等功能,比 IO 更加高效,适用于高并发、大流量的场景。

        在选择 IO 或 NIO 时,需要根据应用场景和需求进行权衡和选择。对于低并发的简单应用,IO 可以满足要求,而对于高并发、大流量的应用,则需要选择 NIO 或 AIO 来提高效率。

猜你喜欢

转载自blog.csdn.net/qq_37761711/article/details/130549638