“关于NIO”的版本间差异
跳到导航
跳到搜索
(→NIO 组件) |
|||
第55行: | 第55行: | ||
== NIO 组件 == | == NIO 组件 == | ||
NIO中的所有I/O都是通过一个通道开始的。数据总是从缓冲区写入通道,并从通道读取到缓冲区: | |||
# 从通道读取:创建一个缓冲区,然后请求通道读取数据; | |||
#: [[File:NIO:数据读取.png|400px]] | |||
# 通道写入:创建一个缓冲区,填充数据,并要求通道写入数据; | |||
#: [[File:NIO:数据写入.png|400px]] | |||
Java NIO 由以下几个核心部分组成: | Java NIO 由以下几个核心部分组成: | ||
* “'''Buffer'''” | |||
* “'''Channel'''” | |||
* “'''Selector'''” | |||
=== Channel === | === Channel === | ||
通道,是用于在实体和字节缓冲区之间有效传输数据的介质。它从一个实体读取数据,并将其放在缓冲区块中以供消费。 | |||
Java NIO Channel 不同于流: | |||
# 既可以从通道中读取数据,又可以写数据到通道;但流的读写通常是单向的。 | |||
# 通道可以异步地读写。 | |||
# 通道中的数据总是要先读到一个Buffer,或者总是要从一个Buffer中写入。 | |||
“java.nio.channels”类的层次结构: | |||
: [[File:java.nio.channels类的层次结构.png|400px]] | |||
其中顶层接口: | |||
<syntaxhighlight lang="java"> | |||
package java.nio.channels; | |||
import java.io.IOException; | |||
import java.io.Closeable; | |||
public interface Channel extends Closeable { | |||
// 检查通道是否打开 | |||
public boolean isOpen(); | |||
// 关闭通道 | |||
public void close() throws IOException; | |||
} | |||
</syntaxhighlight> | |||
Java NIO中,主要使用的通道如下: | |||
# “'''FileChannel'''”:从文件中读写数据; | |||
# “'''DatagramChannel'''”:通过UDP读写网络中的数据; | |||
# “'''SocketChannel'''”:通过TCP读写网络中的数据; | |||
# “'''ServerSocketChannel'''”:监听新进来的TCP连接,像Web服务器那样。对每一个新进来的连接都会创建一个SocketChannel; | |||
示例: | |||
<syntaxhighlight lang="java"> | |||
RandomAccessFile aFile = new RandomAccessFile("data/nio-data.txt", "rw"); | |||
FileChannel inChannel = aFile.getChannel(); | |||
ByteBuffer buf = ByteBuffer.allocate(48); | |||
int bytesRead = inChannel.read(buf); | |||
while (bytesRead != -1) | |||
{ | |||
System.out.println("Read " + bytesRead); | |||
buf.flip(); | |||
while(buf.hasRemaining()) | |||
{ | |||
System.out.print((char) buf.get()); | |||
} | |||
buf.clear(); | |||
bytesRead = inChannel.read(buf); | |||
} | |||
aFile.close(); | |||
</syntaxhighlight> | |||
=== | === Buffer === | ||
第84行: | 第128行: | ||
=== Selector === | |||
== Scatter / Gather == | == Scatter / Gather == |
2021年1月3日 (日) 05:51的版本
关于
Java NIO,即“New I/O”(另一说“No-Blocking I/O”):采用内存映射文件的方式来处理输入输出:NIO将文件或文件的一段区域映射到内存中,这样就可以像访问内存一样访问文件了。
- (相关内容:Java NIO Tutorial,网上资料大多来自于此)
与 IO
NIO与标准IO不同:NIO支持面向缓冲区的、基于通道的IO操作,以更加高效的方式进行文件的读写操作。
- (“旧”的I/O包已经使用NIO重新实现过,“即使我们不显式的使用NIO编程,也能从中受益”)
- (NIO子系统不会取代java.io包中可用的基于流的I/O类)
IO | NIO |
---|---|
面向流(Stream Oritented) | 面向缓冲区(Buffer Oritented) |
阻塞IO(Blocking IO) | 非阻塞IO(None Blocking IO) |
无 | 选择器(Selecters) |
NIO 包
从JDK1.4开始提供的一系列改进的输入/输出处理,这些类都被放在java.nio包及子包下:
包名称 | 使用/目的 |
---|---|
java.nio | NIO系统的顶级包,NIO系统封装了各种类型的缓冲区。 |
java.nio.charset | 封装了字符集,并且还支持分别将字符转换为字节和字节到编码器和解码器的操作。 |
java.nio.charset.spi | 用于支持字符集服务提供者 |
java.nio.channels | 支持通道,这些通道本质上是打开I/O连接。 |
java.nio.channels.spi | 用于支持频道的服务提供者 |
java.nio.file | 提供对文件的支持 |
java.nio.file.spi | 用于支持文件系统的服务提供者 |
java.nio.file.attribute | 用于提供对文件属性的支持 |
(为什么学习NIO)
IO操作往往在两个场景下会用到:
- 文件I/O
- 网络I/O:NIO的优势体现;
【IO:同步、异步,阻塞、非阻塞】
NIO 组件
NIO中的所有I/O都是通过一个通道开始的。数据总是从缓冲区写入通道,并从通道读取到缓冲区:
Java NIO 由以下几个核心部分组成:
- “Buffer”
- “Channel”
- “Selector”
Channel
通道,是用于在实体和字节缓冲区之间有效传输数据的介质。它从一个实体读取数据,并将其放在缓冲区块中以供消费。 Java NIO Channel 不同于流:
- 既可以从通道中读取数据,又可以写数据到通道;但流的读写通常是单向的。
- 通道可以异步地读写。
- 通道中的数据总是要先读到一个Buffer,或者总是要从一个Buffer中写入。
“java.nio.channels”类的层次结构:
其中顶层接口:
package java.nio.channels;
import java.io.IOException;
import java.io.Closeable;
public interface Channel extends Closeable {
// 检查通道是否打开
public boolean isOpen();
// 关闭通道
public void close() throws IOException;
}
Java NIO中,主要使用的通道如下:
- “FileChannel”:从文件中读写数据;
- “DatagramChannel”:通过UDP读写网络中的数据;
- “SocketChannel”:通过TCP读写网络中的数据;
- “ServerSocketChannel”:监听新进来的TCP连接,像Web服务器那样。对每一个新进来的连接都会创建一个SocketChannel;
示例:
RandomAccessFile aFile = new RandomAccessFile("data/nio-data.txt", "rw");
FileChannel inChannel = aFile.getChannel();
ByteBuffer buf = ByteBuffer.allocate(48);
int bytesRead = inChannel.read(buf);
while (bytesRead != -1)
{
System.out.println("Read " + bytesRead);
buf.flip();
while(buf.hasRemaining())
{
System.out.print((char) buf.get());
}
buf.clear();
bytesRead = inChannel.read(buf);
}
aFile.close();
Buffer
Selector
Scatter / Gather
分散(scatter) 聚集(gather)
Channel to Channel Transfers
常用Channel
FileChannel DatagramChannel SocketChannel ServerSocketChannel
Java NIO非阻塞式服务器
其他
Pipe Path Files AsynchronousFileChannel