面试题答案
一键面试在Java AIO编程中,通过实现CompletionHandler
接口来处理异步I/O操作的结果。以下是一个简单的异步文件读取操作并处理读取结果的示例代码:
- 首先创建一个类实现
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();
}
}
- 然后进行异步文件读取操作:
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();
}
}
}
在上述代码中:
ReadCompletionHandler
类实现了CompletionHandler
接口,在completed
方法中处理读取到的数据,将其转换为字符串并打印。如果读取到文件末尾(result == -1
),则关闭文件通道。处理完数据后,重新清空ByteBuffer
并继续读取文件。- 在
AIODemo
类的main
方法中,打开一个文件通道,并通过fileChannel.read
方法进行异步读取。read
方法的最后两个参数分别是ByteBuffer
用于存储数据,以及实现了CompletionHandler
接口的实例,用于处理读取结果。failed
方法用于处理读取过程中的异常,在发生异常时关闭文件通道并打印异常堆栈信息。