>Java >java지도 시간 >Java I/O 스트림의 NIO API는 어떻게 작동합니까?

Java I/O 스트림의 NIO API는 어떻게 작동합니까?

PHPz
PHPz원래의
2024-04-13 21:36:01638검색

Java NIO API는 I/O 작업을 처리하기 위한 고급 API로, 기존 차단 I/O보다 더 나은 성능과 확장성을 제공합니다. 버퍼: 애플리케이션과 운영 체제 간에 전송되는 데이터용 메모리 영역입니다. 채널: 애플리케이션과 I/O 장치 간의 연결을 나타내는 추상적인 개념입니다. 선택기: 여러 채널을 폴링하여 어떤 채널이 읽고 쓸 준비가 되었는지 확인하는 데 사용됩니다.

Java I/O流中的NIO API是如何工作的?

Java I/O 스트리밍의 NIO API: 철저한 분석

Introduction

NIO(Non-Blocking I/O) API는 I/O 작업을 처리하기 위한 Java의 상위 수준 API입니다. 특히 대량의 연결이나 데이터를 처리할 때 기존 차단 I/O보다 더 나은 성능과 확장성을 제공합니다.

NIO API의 구성 요소

NIO API는 다음과 같은 주요 구성 요소로 구성됩니다.

  • 버퍼(버퍼): 애플리케이션과 기본 운영 체제 간에 데이터를 전송하는 데 사용되는 메모리 영역입니다.
  • 채널: 애플리케이션과 I/O 장치 간의 연결을 나타내는 추상적인 개념입니다.
  • 선택기: 읽고 쓸 준비가 된 채널을 결정하기 위해 여러 채널을 폴링하는 데 사용됩니다.

NIO 작동 방식

NIO의 작동은 이벤트 루프를 기반으로 합니다.

  1. 버퍼와 채널을 생성하고 선택기를 초기화합니다.
  2. 선택기에 관심 있는 이벤트를 등록하세요(예: 읽기 가능 또는 쓰기 가능).
  3. 선택기는 등록된 채널을 폴링하여 데이터를 처리할 준비가 된 채널을 결정합니다.
  4. 하나 이상의 채널이 준비되면 선택기는 애플리케이션 스레드를 깨웁니다.
  5. 애플리케이션은 데이터를 읽거나 쓴 다음 선택기에서 채널 등록을 취소합니다.

실용 사례

다음은 NIO API를 사용하여 간단한 서버를 작성하는 예입니다.

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.List;

public class NIOServer {

    private static final int PORT = 8080;
    private static List<SocketChannel> connectedSockets = new ArrayList<>();

    public static void main(String[] args) throws IOException {

        // 创建服务器套接字通道
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();

        // 将服务器通道绑定到端口
        serverSocketChannel.bind(new InetSocketAddress(PORT));

        // 设置非阻塞模式
        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()) {

                    // 接受传入的连接
                    SocketChannel socketChannel = serverSocketChannel.accept();

                    // 设置非阻塞模式
                    socketChannel.configureBlocking(false);

                    // 将套接字通道注册到选择器,感兴趣的可读事件
                    socketChannel.register(selector, SelectionKey.OP_READ);

                    // 添加到已连接套接字列表
                    connectedSockets.add(socketChannel);
                }

                // 可读事件
                else if (key.isReadable()) {

                    SocketChannel socketChannel = (SocketChannel) key.channel();

                    // 读取数据
                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    int bytesRead = socketChannel.read(buffer);

                    // 如果读取到EOF,则关闭套接字
                    if (bytesRead == -1) {
                        socketChannel.close();
                        connectedSockets.remove(socketChannel);
                    }

                    // 处理读取到的数据
                    // ...

                }
            }

            // 清除已处理的键
            selector.selectedKeys().clear();
        }
    }
}

이 예에서 서버는 포트 8080을 수신하고 클라이언트 연결을 수락합니다. 클라이언트가 연결되면 연결된 소켓 목록에 추가됩니다. 서버는 선택기를 사용하여 연결된 소켓을 폴링하여 데이터를 읽고 쓸 준비가 된 소켓을 결정합니다.

위 내용은 Java I/O 스트림의 NIO API는 어떻게 작동합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.