📜  Java NIO与IO(1)

📅  最后修改于: 2023-12-03 14:42:15.518000             🧑  作者: Mango

Java NIO与IO

简介

Java NIO(New IO)是Java标准库中对IO操作的新API。相比之前的IO(普通IO),Java NIO提供了更高效、更灵活的IO操作方式。因此,对于开发大规模并发应用程序而言,Java NIO是一个很好的选择。

区别与优势
阻塞与非阻塞

在传统的IO模型中,当一个线程从输入流中读取数据时,如果数据未准备好,则该线程将被阻塞,直到数据准备好。而在Java NIO中,线程可以在数据准备好之前继续执行其他任务,也就是说,可以在数据未准备好时继续处理其他的IO操作,这使得程序具有更高的并发性能。

缓冲区

Java NIO使用缓冲区读写数据,可以大大提高IO的效率。缓冲区可以一次性读写一块数据,而不是一个字节地读写。

通道与选择器

Java NIO中引入了通道(Channel)的概念,可以同时读取和写入数据。通道是双向的,可以从通道中读取数据,也可以写入数据到通道。与通道相配合的是选择器(Selector),选择器可以同时监视多个通道的IO状态,从而在某个通道就绪时进行相应的处理。

使用Java NIO
读取数据

下面是读取数据的示例代码片段:

// 创建一个文件输入流
FileInputStream fis = new FileInputStream("example.txt");
// 创建一个通道
FileChannel channel = fis.getChannel();
// 创建一个缓冲区
ByteBuffer buffer = ByteBuffer.allocate(1024);

while (channel.read(buffer) != -1) {
    buffer.flip(); // 切换为读模式
    while (buffer.hasRemaining()) {
        System.out.print((char) buffer.get()); // 从缓冲区读取数据
    }
    buffer.clear(); // 清空缓冲区,准备读取下一块数据
}

channel.close();
fis.close();
写入数据

下面是写入数据的示例代码片段:

// 创建一个文件输出流
FileOutputStream fos = new FileOutputStream("example.txt");
// 创建一个通道
FileChannel channel = fos.getChannel();
// 创建一个缓冲区
ByteBuffer buffer = ByteBuffer.allocate(1024);

String data = "Hello, World!";
buffer.put(data.getBytes()); // 将数据写入缓冲区
buffer.flip(); // 切换为读模式
channel.write(buffer); // 将缓冲区的数据写入通道

channel.close();
fos.close();
使用选择器

下面是使用选择器的示例代码片段:

Selector selector = Selector.open();
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false); // 设置为非阻塞模式
serverSocketChannel.socket().bind(new InetSocketAddress(8080));
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

while (true) {
    int readyChannels = selector.select();
    if (readyChannels == 0) {
        continue;
    }

    Set<SelectionKey> selectedKeys = selector.selectedKeys();
    Iterator<SelectionKey> keyIterator = selectedKeys.iterator();

    while (keyIterator.hasNext()) {
        SelectionKey key = keyIterator.next();

        if (key.isAcceptable()) {
            // 处理连接请求
        }

        if (key.isReadable()) {
            // 处理读事件
        }

        if (key.isWritable()) {
            // 处理写事件
        }

        if (key.isConnectable()) {
            // 处理连接完成事件
        }

        keyIterator.remove();
    }
}

serverSocketChannel.close();
总结

Java NIO提供了更高效、更灵活的IO操作方式,适用于开发大规模并发应用程序。本文介绍了Java NIO与传统IO的区别与优势,并给出了使用Java NIO的示例代码片段。在实际开发中,根据具体需求选择适合的IO模型是非常重要的,Java NIO是一个值得学习和应用的技术。