java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java处理I/O操作

Java中处理I/O操作的不同方式

作者:IT小辉同学

BIO、NIO和AIO是Java中处理I/O操作的三种不同方式,它们分别代表阻塞I/O、非阻塞I/O和异步I/O,本文我们结合代码进行一个综合演示,代码由于是伪代码,可能存在不足,仅供大家参考

Java中处理I/O操作的不同方式:BIO,NIO,AIO

首先,我们需要知道,Java中处理I/O操作的不同方式的不同方式有几种。

BIO、NIO和AIO是Java中处理I/O操作的三种不同方式,它们分别代表阻塞I/O、非阻塞I/O和异步I/O。下面是对它们的详细介绍,在这里我们结合代码进行一个综合演示,代码由于是伪代码,可能存在不足,仅供大家参考:

BIO(Blocking I/O)阻塞I/O:

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class BlockingIOServer {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(8888);

        while (true) {
            Socket clientSocket = serverSocket.accept(); // 阻塞等待客户端连接
            InputStream inputStream = clientSocket.getInputStream();
            // 处理输入流,阻塞直到数据可读
            int data = inputStream.read();
            System.out.println("Received data: " + data);

            // 其他业务逻辑处理
        }
    }
}

NIO(Non-blocking I/O)非阻塞I/O:

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

public class NonBlockingIOServer {
    public static void main(String[] args) throws IOException {
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.bind(new InetSocketAddress(8888));
        serverSocketChannel.configureBlocking(false);

        Selector selector = Selector.open();
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

        while (true) {
            selector.select();
            Set<SelectionKey> selectedKeys = selector.selectedKeys();
            Iterator<SelectionKey> keyIterator = selectedKeys.iterator();

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

                if (key.isAcceptable()) {
                    // 处理连接
                    SocketChannel clientChannel = serverSocketChannel.accept();
                    clientChannel.configureBlocking(false);
                    clientChannel.register(selector, SelectionKey.OP_READ);
                } else if (key.isReadable()) {
                    // 处理读事件
                    SocketChannel clientChannel = (SocketChannel) key.channel();
                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    int bytesRead = clientChannel.read(buffer);
                    System.out.println("Received data: " + new String(buffer.array(), 0, bytesRead));

                    // 其他业务逻辑处理

                    clientChannel.close();
                }

                keyIterator.remove();
            }
        }
    }
}

AIO(Asynchronous I/O)异步I/O:

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;

public class AsyncIOServer {
    public static void main(String[] args) throws IOException {
        AsynchronousServerSocketChannel serverSocketChannel = AsynchronousServerSocketChannel.open();
        serverSocketChannel.bind(new InetSocketAddress(8888));

        serverSocketChannel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() {
            @Override
            public void completed(AsynchronousSocketChannel clientChannel, Void attachment) {
                serverSocketChannel.accept(null, this);
                // 继续接收下一个连接
                ByteBuffer buffer = ByteBuffer.allocate(1024);
                clientChannel.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() {
                    @Override
                    public void completed(Integer bytesRead, ByteBuffer buffer) {
                        System.out.println("Received data: " + new String(buffer.array(), 0, bytesRead));
                        // 其他业务逻辑处理
                        clientChannel.close();
                    }

                    @Override
                    public void failed(Throwable exc, ByteBuffer buffer) {
                        // 处理读取失败
                    }
                });
            }

            @Override
            public void failed(Throwable exc, Void attachment) {
                // 处理接受连接失败
            }
        });

        // 阻塞主线程,保持服务端运行
        try {
            Thread.sleep(Integer.MAX_VALUE);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

总的来说,BIO适用于连接数较少且连接时间较长的场景,NIO适用于连接数较多但每个连接的交互时间短的场景,而AIO适用于连接数较多且每个连接的交互时间不确定的场景。选择合适的I/O模型取决于具体的应用需求。在Java中,NIO和AIO是在Java 1.4 和 Java 7 中引入的,分别位于java.niojava.nio.channels包中。

以上就是Java中处理I/O操作的不同方式的详细内容,更多关于Java处理I/O操作的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文