Java的I/O模型是Java编程中处理数据输入和输出的核心机制。Java提供了多种I/O模型来适应不同的应用场景,以下将详细介绍Java中的五大I/O模型,并给出相应的代码实践。
1. 同步阻塞IO(BIO)
BIO是Java传统I/O模型,它基于流和线程。在BIO模型中,当线程发起I/O请求时,它将被阻塞,直到I/O操作完成。
1.1 示例代码
以下是一个简单的BIO客户端和服务端示例:
// BIO客户端
public class BioClient {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("localhost", 8080);
OutputStream outputStream = socket.getOutputStream();
outputStream.write("Hello, BIO!".getBytes());
outputStream.flush();
socket.close();
}
}
// BIO服务端
public class BioServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8080);
while (true) {
Socket socket = serverSocket.accept();
new Thread(new BioHandler(socket)).start();
}
}
}
class BioHandler implements Runnable {
private Socket socket;
public BioHandler(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
InputStream inputStream = socket.getInputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = inputStream.read(buffer)) != -1) {
System.out.println(new String(buffer, 0, len));
}
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
2. 同步非阻塞IO(NIO)
NIO是Java 1.4引入的,它提供了非阻塞I/O操作和缓冲区概念。在NIO中,使用Selector来监听多个通道(Channel)的状态。
2.1 示例代码
以下是一个简单的NIO客户端和服务端示例:
// NIO客户端
public class NioClient {
public static void main(String[] args) throws IOException {
SocketChannel socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
socketChannel.connect(new InetSocketAddress("localhost", 8080));
ByteBuffer buffer = ByteBuffer.allocate(1024);
buffer.put("Hello, NIO!".getBytes());
buffer.flip();
socketChannel.write(buffer);
socketChannel.close();
}
}
// NIO服务端
public class NioServer {
public static void main(String[] args) throws IOException {
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
serverSocketChannel.bind(new InetSocketAddress(8080));
Selector selector = Selector.open();
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
selector.select();
Set<SelectionKey> keys = selector.selectedKeys();
Iterator<SelectionKey> keyIterator = keys.iterator();
while (keyIterator.hasNext()) {
SelectionKey key = keyIterator.next();
if (key.isAcceptable()) {
SocketChannel clientSocketChannel = serverSocketChannel.accept();
clientSocketChannel.configureBlocking(false);
clientSocketChannel.register(selector, SelectionKey.OP_READ);
} else if (key.isReadable()) {
SocketChannel socketChannel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
int len = socketChannel.read(buffer);
if (len > 0) {
System.out.println(new String(buffer.array(), 0, len));
}
}
keyIterator.remove();
}
}
}
}
3. 异步非阻塞IO(AIO)
AIO是NIO的改进版,它提供异步I/O操作,允许用户线程在I/O操作完成时接收通知。
3.1 示例代码
以下是一个简单的AIO客户端和服务端示例:
// AIO客户端
public class AioClient {
public static void main(String[] args) throws IOException {
AsynchronousSocketChannel client = AsynchronousSocketChannel.open();
ByteBuffer buffer = ByteBuffer.allocate(1024);
client.connect(new InetSocketAddress("localhost", 8080), buffer, new CompletionHandler<AsynchronousSocketChannel, ByteBuffer>() {
@Override
public void completed(AsynchronousSocketChannel result, ByteBuffer attachment) {
attachment.flip();
try {
result.write(attachment);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
exc.printStackTrace();
}
});
try {
client.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
client.close();
}
}
// AIO服务端
public class AioServer {
public static void main(String[] args) throws IOException {
AsynchronousServerSocketChannel server = AsynchronousServerSocketChannel.open();
server.bind(new InetSocketAddress(8080));
server.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() {
@Override
public void completed(AsynchronousSocketChannel result, Void attachment) {
server.accept(null, this);
ByteBuffer buffer = ByteBuffer.allocate(1024);
result.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() {
@Override
public void completed(Integer result, ByteBuffer attachment) {
attachment.flip();
try {
System.out.println(new String(attachment.array(), 0, result));
result.write(attachment);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void failed(Throwable exc, ByteBuffer attachment) {
exc.printStackTrace();
}
});
}
@Override
public void failed(Throwable exc, Void attachment) {
exc.printStackTrace();
}
});
try {
server.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
server.close();
}
}
4. 高级IO(High-Performance I/O)
高级IO是一种基于NIO的框架,如Netty,它提供高性能的网络编程支持。
4.1 示例代码
以下是一个简单的Netty客户端和服务端示例:
// Netty客户端
public class NettyClient {
public static void main(String[] args) {
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new SimpleChannelInboundHandler<String>() {
@Override
protected void channelRead0(ChannelHandlerContext ctx, String msg) {
System.out.println(msg);
}
});
}
});
ChannelFuture future = bootstrap.connect(new InetSocketAddress("localhost", 8080)).sync();
future.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
group.shutdownGracefully();
}
}
}
// Netty服务端
public class NettyServer {
public static void main(String[] args) {
EventLoopGroup group = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(group)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new SimpleChannelInboundHandler<String>() {
@Override
protected void channelRead0(ChannelHandlerContext ctx, String msg) {
System.out.println(msg);
ctx.writeAndFlush("Hello from server!");
}
});
}
});
ChannelFuture f = b.bind(8080).sync();
f.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
group.shutdownGracefully();
}
}
}
5. 总结
Java提供了多种I/O模型,包括BIO、NIO、AIO、高级IO等。这些模型适用于不同的应用场景,选择合适的模型可以提高应用程序的性能和效率。在本文中,我们详细介绍了这些模型的原理和代码实践,希望对您有所帮助。
