结合JavaGuideIO部分内容食用更佳
在Java中,I/O(输入/输出)操作主要有三种模型:BIO(Blocking I/O,阻塞I/O)、NIO(Non-blocking I/O,非阻塞I/O)和AIO(Asynchronous I/O,异步I/O)。这三种模型在处理I/O操作时的工作方式和适用场景各不相同。下面对它们进行详细介绍:
// 服务器端
ServerSocket serverSocket = new ServerSocket(8080);
while (true) {
Socket clientSocket = serverSocket.accept(); // 阻塞等待连接
new Thread(() -> {
try {
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream())
);
String message = in.readLine();
System.out.println("Received: " + message);
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}).start();
}
// 客户端
Socket socket = new Socket("localhost", 8080);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
out.println("Hello, Server!");
socket.close();
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
public class NioServer {
public static void main(String[] args) throws IOException {
// 打开ServerSocketChannel
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.configureBlocking(false);
serverChannel.socket().bind(new InetSocketAddress(8080));
// 打开Selector
Selector selector = Selector.open();
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
ByteBuffer buffer = ByteBuffer.allocate(256);
while (true) {
selector.select(); // 阻塞直到有事件
for (SelectionKey key : selector.selectedKeys()) {
if (key.isAcceptable()) {
// 接受连接
ServerSocketChannel srvChannel = (ServerSocketChannel) key.channel();
SocketChannel client = srvChannel.accept();
client.configureBlocking(false);
client.register(selector, SelectionKey.OP_READ);
} else if (key.isReadable()) {
// 读取数据
SocketChannel client = (SocketChannel) key.channel();
buffer.clear();
int bytesRead = client.read(buffer);
if (bytesRead == -1) {
client.close();
} else {
buffer.flip();
byte[] data = new byte[buffer.limit()];
buffer.get(data);
System.out.println("Received: " + new String(data));
}
}
}
selector.selectedKeys().clear();
}
}
}
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;
import java.util.concurrent.Future;
public class AioServer {
public static void main(String[] args) throws IOException {
final AsynchronousServerSocketChannel serverChannel =
AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(8080));
serverChannel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() {
@Override
public void completed(AsynchronousSocketChannel client, Void attachment) {
// 继续接受下一个连接
serverChannel.accept(null, this);
// 处理当前连接
ByteBuffer buffer = ByteBuffer.allocate(1024);
client.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer bytesRead, ByteBuffer buf) {
if (bytesRead == -1) {
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
return;
}
buf.flip();
byte[] data = new byte[buf.limit()];
buf.get(data);
System.out.println("Received: " + new String(data));
buf.clear();
client.read(buf, buf, this);
}
@Override
public void failed(Throwable exc, ByteBuffer buf) {
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
@Override
public void failed(Throwable exc, Void attachment) {
System.err.println("Failed to accept a connection.");
exc.printStackTrace();
}
});
// 阻止主线程退出
try {
Thread.currentThread().join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}