在 Java 编程中,输入输出(IO)是不可或缺的部分,随着技术的发展,Java 的 IO 系统也经历了显著的变化。本文将深入探讨 Java IO 和 NIO 的历史、优缺点以及适用场景。
Java IO 包(java.io
)自 Java 1.0 以来就存在,最初设计用于简单的数据输入和输出。Java IO 采用阻塞式模型,这意味着当一个线程进行 IO 操作时,线程会被阻塞,直到操作完成。这种设计虽然简单,但在高并发环境下可能导致性能瓶颈。
Java IO 的主要组成部分分为两大类:
InputStream
OutputStream
Reader
Writer
以下代码示例展示了如何使用 Java IO 进行文件复制操作:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileCopy {
public static void main(String[] args) {
String sourcePath = "source.txt";
String destPath = "dest.txt";
try (FileInputStream fis = new FileInputStream(sourcePath);
FileOutputStream fos = new FileOutputStream(destPath)) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
fos.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Java NIO(Non-blocking I/O)是在 Java 1.4 中引入的,目的是解决传统 IO 的一些局限性。NIO 支持非阻塞式和选择器模型,使得一个线程可以同时管理多个 IO 通道,从而显著提高了处理并发的能力。
NIO 的核心组件包括:
以下是各个核心组件的示例代码:
import java.nio.ByteBuffer;
public class BufferExample {
public static void main(String[] args) {
ByteBuffer buffer = ByteBuffer.allocate(10);
buffer.put((byte) 1);
buffer.put((byte) 2);
buffer.flip(); // 切换为读取模式
while (buffer.hasRemaining()) {
System.out.println(buffer.get());
}
}
}
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.file.StandardOpenOption;
import java.nio.file.Paths;
public class ChannelExample {
public static void main(String[] args) {
try (FileChannel channel = FileChannel.open(Paths.get("example.txt"), StandardOpenOption.READ)) {
System.out.println("文件大小: " + channel.size() + " 字节");
} catch (IOException e) {
e.printStackTrace();
}
}
}
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
public class SelectorExample {
public static void main(String[] args) {
try {
Selector selector = Selector.open();
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.bind(new InetSocketAddress(8080));
serverSocketChannel.configureBlocking(false);
serverSocketChannel.register(selector, serverSocketChannel.validOps());
System.out.println("服务器已启动,等待连接...");
} catch (IOException e) {
e.printStackTrace();
}
}
}
特性 | Java IO | Java NIO | 常用开源组件 |
---|---|---|---|
模型 | 阻塞式 | 非阻塞式 | Netty(NIO) |
并发能力 | 低 | 高 | Spring WebFlux(NIO) |
API复杂性 | 简单 | 复杂 | Apache MINA(NIO) |
学习曲线 | 平缓 | 陡峭 | |
适用场景 | 小型项目,简单任务 | 高并发,大流量应用 |
Java 的 IO 和 NIO 各有优缺点,选择合适的技术栈取决于具体的应用需求。在高并发和大数据量的环境下,NIO 更具优势;而在简单文件操作和小型项目中,传统的 IO 方式更为便捷。