Java NIO 的核心组件包括:缓冲区(Buffer)、通道(Channel)、选择器(Selector)和文件操作(File)。
1、缓冲区(Buffer):缓冲区是一个容器,可以在缓冲区中读写数据,Java NIO 中的所有 IO 操作都是通过缓冲区来完成的。缓冲区提供了访问底层数据的方法,并且在读取或写入数据时,缓冲区会自动维护当前位置、上限和容量等状态信息。
2、通道(Channel):通道是双向的,可以读取和写入数据,通道提供了在底层 I/O 设备上进行数据传输的方法,Java NIO 的通道比传统 IO 流更灵活,可以同时支持异步操作和阻塞操作。
3、选择器(Selector):选择器可以同时监控多个通道的 I/O 状态,以此实现单线程同时管理多个 I/O 通道的读写操作。选择器可以监听某个或某些事件的发生,当某个事件发生时,选择器会自动触发相应的操作。
4、文件操作(File):Java NIO 提供了对文件的支持,可以使用通道来操作文件,例如读取文件内容、写入文件内容等。
下面以 Channel 和 Buffer 为例,简单讲解一下它们的作用和使用方法:
Channel:通道是对底层操作系统的 I/O 设备的一个抽象,通过通道可以读取和写入数据。在 Java NIO 中,通道提供了一种更高效的数据传输方式,相比传统 IO 流,通道可以实现非阻塞式的 I/O 操作,同时也支持异步 I/O 操作。
Buffer:缓冲区是一个临时存储区域,用于在通道和程序之间进行数据交换。在 Java NIO 中,所有的数据读写操作都是通过缓冲区来完成的。缓冲区分为直接缓冲区和非直接缓冲区两种,直接缓冲区可以映射到物理内存中,可以更快地进行数据交换,但也需要更多的系统资源。
下面是一个使用通道和缓冲区进行文件读取和写入的示例:
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class NioExample {
public static void main(String[] args) {
RandomAccessFile fromFile = null;
RandomAccessFile toFile = null;
try {
// 从文件创建输入输出流
fromFile = new RandomAccessFile("from.txt", "rw");
toFile = new RandomAccessFile("to.txt", "rw");
// 从输入输出流获取通道
FileChannel fromChannel = fromFile.getChannel();
FileChannel toChannel = toFile.getChannel();
// 创建一个缓冲区
ByteBuffer buffer = ByteBuffer.allocate(1024);
// 从通道中读取数据到缓冲区
int bytesRead = fromChannel.read(buffer);
while (bytesRead != -1) {
// 将缓冲区切换到写模式
buffer.flip();
// 从缓冲区写入数据到通道
toChannel.write(buffer);
// 将缓冲区切换到读模式,以便下一次读取
buffer.clear();
bytesRead = fromChannel.read(buffer);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fromFile != null) {
fromFile.close();
}
if (toFile != null) {
toFile.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
这个示例演示了从一个文件读取数据并写入到另一个文件的过程。在这个过程中,使用了FileChannel和ByteBuffer两个核心组件。从文件创建输入输出流之后,通过调用getChannel()方法获取对应的通道。接着创建一个ByteBuffer缓冲区,通过调用通道的read()方法将数据读取到缓冲区中,再通过将缓冲区切换到写模式并调用通道的write()方法将数据写入到另一个文件中。最后关闭输入输出流。