Java NIO入门与高效IO
发布时间: 2024-02-25 20:26:48 阅读量: 12 订阅数: 18
# 1. Java IO与NIO简介
## 1.1 Java IO的特点和局限性
在Java中,最初的IO(Input/Output)模型是基于流(Stream)的,其中InputStream和OutputStream负责读取和写入数据。这种IO模型的特点是简单易用,但在处理大量数据时效率比较低下,因为它是阻塞式的,即在IO操作时会阻塞当前线程,等待数据的读取或写入。
然而,随着计算机系统的发展和网络应用的普及,传统的Java IO模型面临一些局限性,比如难以实现非阻塞IO和异步IO等。
## 1.2 Java NIO的优势和特点
Java NIO(New IO)是Java 1.4引入的新IO模型,它提供了更加灵活、高效的IO操作方式。NIO通过Buffer、Channel和Selector来完成IO操作,相比于传统IO模型,NIO有以下优势:
- 非阻塞IO:NIO支持非阻塞IO,可在一个线程中处理多个通道,提高IO效率。
- 可拓展性:NIO的Channel可以同时支持读写操作,可以注册Selector来选择感兴趣的事件。
- 内存映射文件:NIO可以直接将文件映射到内存,实现零拷贝的文件操作。
- 多路复用:Selector可以同时管理多个Channel,实现单线程处理多个通道。
## 1.3 Java NIO与Java IO的区别
Java NIO相比于传统IO有明显的区别:
- 通道中的数据可以双向传输,而流是单向的。
- NIO采用缓冲区操作数据,IO流直接操作数据。
- NIO支持选择器,可以实现单线程处理多个通道。而IO流是阻塞式的,在读写数据时会阻塞当前线程。
# 2. Java NIO核心组件
### 2.1 Buffer缓冲区
缓冲区是NIO中用于数据存储和传输的核心对象,它是一个连续的、有限的、特定原始类型数据元素的线性有序集合。在NIO中,所有数据都是用缓冲区处理的。常用的缓冲区类有ByteBuffer、CharBuffer、ShortBuffer、IntBuffer、LongBuffer、FloatBuffer和DoubleBuffer等。
```java
// 示例代码:创建一个ByteBuffer缓冲区
ByteBuffer buffer = ByteBuffer.allocate(48);
```
**代码说明:** 上面的代码创建了一个容量为48个字节的ByteBuffer缓冲区。
### 2.2 Channel通道
通道是NIO中用于原始数据的I/O操作的对象,它类似于传统IO中的流。通道可以实现双向数据传输,而且大多数通道都是全双工的。常用的通道类有FileChannel、DatagramChannel、SocketChannel和ServerSocketChannel等。
```java
// 示例代码:使用FileChannel从文件中读取数据
FileInputStream fis = new FileInputStream("input.txt");
FileChannel channel = fis.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(48);
int bytesRead = channel.read(buffer);
```
**代码说明:** 上面的代码使用FileChannel从文件中读取数据,并存储到ByteBuffer缓冲区中。
### 2.3 Selector选择器
选择器是NIO中用于多路复用的对象,它可以通过单独的线程处理多个通道的I/O操作。Selector能够检测多个通道上是否有I/O事件(例如:连接打开、数据到达)发生,并且能够处理这些事件。
```java
// 示例代码:创建一个Selector并注册通道
Selector selector = Selector.open();
channel.configureBlocking(false);
SelectionKey key = channel.register(selector, SelectionKey.OP_READ);
```
**代码说明:** 上面的代码创建了一个Selector对象,并注册了一个通道,关注读事件。
### 2.4 Buffer、Channel和Selector之间的关系
在NIO中,Buffer负责对数据的存储和传输,Channel负责数据的读写操作,而Selector可以实现多路复用,使得单个线程可以管理多个Channel。它们之间的关系是紧密联系的,三者共同构成了NIO的核心组件。
通过本章节的学习,我们了解了NIO的核心组件,分别是Buffer、Channel和Selector。在下一章节中,我们将学习如何使用Java NIO进行文件IO操作。
# 3. 使用Java NIO进行文件IO操作
在本章节中,我们将学习如何使用Java NIO进行文件IO操作,包括通过Channel读写文件、使用Buffer来读写数据以及实现文件复制和文件传输等内容。
#### 3.1 通过Channel读写文件
首先,我们需要创建一个文件输入流和一个文件输出流,然后通过这两个流获取对应的Channel,使用Channel进行文件的读写操作。
```java
try (FileInputStream fis = new FileInputStream("input.txt");
FileOutputStream fos = new FileOutputStream("output.txt")) {
FileChannel inputChannel = fis.getChannel();
FileChannel outputChannel = fos.getChannel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
while (inputChannel.read(buffer) != -1) {
buffer.flip();
outputChannel.write(buffer);
buffer.clear();
}
} catch (IOException e) {
e.printStackTrace();
}
```
上述代码中,我们首先创建了一个ByteBuffer作为缓冲区,然后通过i
0
0