首页
学习
活动
专区
圈层
工具
发布

java的NIO编程

Java NIO(New I/O)是一种可伸缩且非阻塞的 I/O,与传统的 Java IO 不同。它允许同时处理多个连接,并且能够更快地处理 I/O 操作,是构建高性能、可伸缩和并发应用程序的重要组成部分。

Java NIO 的核心是 Channel、Buffer 和 Selector。Channel 是连接源和目标的通道,Buffer 是数据传输的缓冲区,Selector 用于监视 Channel 中的事件并选择可用的 Channel 进行操作。下面我们来看一下 Java NIO 的示例。

Channel

在 Java NIO 中,所有的 I/O 操作都是通过 Channel 来进行的。Channel 类似于传统的流,但又有所不同。在 Channel 中,数据可以从 Channel 中读取到 Buffer 中,也可以将数据从 Buffer 写入 Channel 中。

下面是一个从文件中读取数据并输出到控制台的示例:

代码语言:javascript
复制
javaCopy codeimport java.io.*;
import java.nio.*;
import java.nio.channels.*;

public class ChannelExample {
    public static void main(String[] args) throws IOException {
        RandomAccessFile file = new RandomAccessFile("test.txt", "rw");
        FileChannel channel = file.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();
        file.close();
    }
}

在上述示例中,我们使用 FileChannel 打开一个文件,并使用 ByteBuffer 分配一个缓冲区。然后使用 channel.read() 方法从文件中读取数据到缓冲区,使用 buffer.flip() 方法将缓冲区的指针移到缓冲区的起始位置,并使用 buffer.hasRemaining() 和 buffer.get() 方法遍历缓冲区中的数据。

Buffer

Buffer 是一个用于读写数据的缓冲区,它可以存储任何类型的数据,例如字节、字符、整数等等。Buffer 是一个抽象类,主要有以下几种子类:ByteBuffer、CharBuffer、ShortBuffer、IntBuffer、LongBuffer、FloatBuffer 和 DoubleBuffer。

下面是一个使用 ByteBuffer 存储数据并将其输出到控制台的示例:

代码语言:javascript
复制
import java.nio.*;

public class BufferExample {
    public static void main(String[] args) {
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        buffer.put("Hello, world!".getBytes());
        buffer.flip();
        while (buffer.hasRemaining()) {
            System.out.print((char) buffer.get());
        }
        buffer.clear();
    }
}

在上述示例中,我们使用 ByteBuffer 分配一个缓冲区,并使用 put() 方法将一个字符串存储到缓冲区中。然后使用 flip() 方法将缓冲区的指针移到缓冲区的起始位置,并使用 hasRemaining() 和 get() 方法遍历缓冲区中的数据。

Selector

Selector 用于监视 Channel 中的事件并选择可用的 Channel 进行操作。在 Java NIO 中,一个线程可以同时处理多个连接,因此它比传统的 Java IO 更快和更可伸缩。

下面是一个使用 Selector 监视 Channel 的示例:

代码语言:javascript
复制
javaCopy codeimport java.io.*;
import java.nio.*;
import java.nio.channels.*;

public class SelectorExample {
    public static void main(String[] args) throws IOException {
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.socket().bind(new InetSocketAddress("localhost", 8080));
        serverSocketChannel.configureBlocking(false);
        Selector selector = Selector.open();
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        while (true) {
            int readyChannels = selector.select();
            if (readyChannels == 0) {
                continue;
            }
            for (SelectionKey key : selector.selectedKeys()) {
                if (key.isAcceptable()) {
                    ServerSocketChannel server = (ServerSocketChannel) key.channel();
                    SocketChannel client = server.accept();
                    client.configureBlocking(false);
                    client.register(selector, SelectionKey.OP_READ);
                } else if (key.isReadable()) {
                    SocketChannel client = (SocketChannel) key.channel();
                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    client.read(buffer);
                    buffer.flip();
                    while (buffer.hasRemaining()) {
                        System.out.print((char) buffer.get());
                    }
                }
                selector.selectedKeys().remove(key);
            }
        }
    }
}

在上述示例中,我们使用 ServerSocketChannel 打开一个服务器,并使用 Selector 监视该服务器。当有客户端连接时,使用 accept() 方法获取客户端的 SocketChannel 并注册到 Selector 中,并指定监听 OP_READ 事件。当客户端向服务器发送数据时,使用 read() 方法将数据读取到 ByteBuffer 中,并使用 buffer.hasRemaining() 和 buffer.get() 方法遍历 ByteBuffer 中的数据。

下一篇
举报
领券