MST

星途 面试题库

面试题:Java AIO异步编程模型实现细节

在Java AIO编程中,如何通过CompletionHandler接口来处理异步I/O操作的结果?请结合实际代码示例,说明如何创建一个简单的异步文件读取操作并处理读取结果。
30.7万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

在Java AIO编程中,通过实现CompletionHandler接口来处理异步I/O操作的结果。以下是一个简单的异步文件读取操作并处理读取结果的示例代码:

  1. 首先创建一个类实现CompletionHandler<Integer, ByteBuffer>接口,Integer表示读取到的字节数,ByteBuffer用于存储读取的数据。
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;

public class ReadCompletionHandler implements CompletionHandler<Integer, ByteBuffer> {

    private AsynchronousSocketChannel channel;

    public ReadCompletionHandler(AsynchronousSocketChannel channel) {
        this.channel = channel;
    }

    @Override
    public void completed(Integer result, ByteBuffer buffer) {
        if (result == -1) {
            try {
                channel.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return;
        }
        buffer.flip();
        byte[] data = new byte[buffer.remaining()];
        buffer.get(data);
        try {
            String msg = new String(data, "UTF-8");
            System.out.println("Received: " + msg);
        } catch (Exception e) {
            e.printStackTrace();
        }
        buffer.clear();
        channel.read(buffer, buffer, this);
    }

    @Override
    public void failed(Throwable exc, ByteBuffer attachment) {
        try {
            channel.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        exc.printStackTrace();
    }
}
  1. 然后进行异步文件读取操作:
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.nio.channels.FileChannel;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

public class AIODemo {
    public static void main(String[] args) {
        try (FileChannel fileChannel = FileChannel.open(Paths.get(new File("test.txt").toURI()), StandardOpenOption.READ)) {
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            fileChannel.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() {
                @Override
                public void completed(Integer result, ByteBuffer buffer) {
                    if (result == -1) {
                        try {
                            fileChannel.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        return;
                    }
                    buffer.flip();
                    byte[] data = new byte[buffer.remaining()];
                    buffer.get(data);
                    try {
                        String content = new String(data, "UTF-8");
                        System.out.println("File content: " + content);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    buffer.clear();
                    fileChannel.read(buffer, buffer, this);
                }

                @Override
                public void failed(Throwable exc, ByteBuffer attachment) {
                    try {
                        fileChannel.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    exc.printStackTrace();
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在上述代码中:

  1. ReadCompletionHandler类实现了CompletionHandler接口,在completed方法中处理读取到的数据,将其转换为字符串并打印。如果读取到文件末尾(result == -1),则关闭文件通道。处理完数据后,重新清空ByteBuffer并继续读取文件。
  2. AIODemo类的main方法中,打开一个文件通道,并通过fileChannel.read方法进行异步读取。read方法的最后两个参数分别是ByteBuffer用于存储数据,以及实现了CompletionHandler接口的实例,用于处理读取结果。failed方法用于处理读取过程中的异常,在发生异常时关闭文件通道并打印异常堆栈信息。