Maison  >  Article  >  Java  >  Comment fonctionne l'API NIO dans les flux d'E/S Java ?

Comment fonctionne l'API NIO dans les flux d'E/S Java ?

PHPz
PHPzoriginal
2024-04-13 21:36:01580parcourir

L'API Java NIO est une API avancée pour la gestion des opérations d'E/S, qui offre de meilleures performances et évolutivité que le blocage traditionnel des E/S : Tampons : transférés entre les applications et les systèmes d'exploitation Zone mémoire pour les données. Canaux : concept abstrait qui représente la connexion entre une application et un périphérique d'E/S. Sélecteurs : utilisés pour interroger plusieurs canaux afin de déterminer quels canaux sont prêts à être lus et écrits.

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

API NIO dans Java I/O Streaming : une analyse approfondie

Introduction

L'API NIO (Non-Blocking I/O) est une API de niveau supérieur en Java pour la gestion des opérations d'E/S. Il offre de meilleures performances et une meilleure évolutivité que les E/S bloquantes traditionnelles, en particulier lors de la gestion de grandes quantités de connexions ou de données.

Composants de l'API NIO

L'API NIO se compose des principaux composants suivants :

  • Buffers (Buffers) : Une zone mémoire utilisée pour transférer des données entre une application et le système d'exploitation sous-jacent.
  • Canaux : Concept abstrait qui représente la connexion entre les applications et les périphériques d'E/S.
  • Sélecteurs : Utilisés pour interroger plusieurs chaînes afin de déterminer quelles chaînes sont prêtes à être lues et écrites.

Comment fonctionne NIO

Le fonctionnement de NIO est basé sur une boucle d'événements :

  1. Créer des buffers et des canaux, initialiser des sélecteurs.
  2. Enregistrez les événements d'intérêt sur le sélecteur (par exemple lisibles ou inscriptibles).
  3. Les sélecteurs interrogent les chaînes enregistrées pour déterminer quelles chaînes sont prêtes à gérer les données.
  4. Le sélecteur réveille le fil d'application lorsqu'une ou plusieurs chaînes sont prêtes.
  5. L'application lit ou écrit des données puis désenregistre la chaîne sur le sélecteur.

Cas pratique

Voici un exemple d'écriture d'un serveur simple utilisant l'API NIO :

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();
        }
    }
}

Dans cet exemple, le serveur écoute le port 8080 et accepte les connexions clients. Lorsqu'un client se connecte, il est ajouté à une liste de sockets connectés. Le serveur utilise des sélecteurs pour interroger les sockets connectés afin de déterminer quels sockets sont prêts à lire et à écrire des données.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn