总结了才知道, 原来 Java NIO 的 channel 是这么用的!
Channel 类似于在类似 Unix 的“文件描述符”。
与缓冲区不同,Channel 不能被重复使用,一个打开的 Channel 即代表与一个特定 I/O 服务的特定连接,并封装该连接的状态。当 Channel 关闭时,那个连接会丢失,然后 Channel 将不再连接任何东西。
FileChannel(java.nio.channels.FileChannel)可以使用任意缓冲区,但也可以使用 m-map 建立直接映射到文件内容的缓冲区。它们还可以与文件系统锁进行交互。同样,SocketChannel(java.nio.channels.SocketChannel 和 java.nio.channels.ServerSocketChannel)允许在 Socket 和 NIO 缓冲区之间进行数据传输。
FileChannel 可用于进行文件复制,这可能比对字节数组使用旧的读/写方式要有效得多。典型用法:
// 获得 file channels
try(FileChannel in = FileChannel.open(source, StandardOpenOption.READ);
FileChannel out = FileChannel.open(target, StandardOpenOption.WRITE)
){
// JavaVM does its best to do this as native I/O operations.
in.transferTo(0, in.size(), out);
}
===========================================================================
Java NIO 中最重要的 Channel 的实现:
FileChannel
从文件中读写数据
DatagramChannel
通过 UDP 读写网络中的数据
SocketChannel
通过 TCP 读写网络中的数据
ServerSocketChannel
监听新进来的 TCP 连接,像 Web 服务器那样。对每一个新进来的连接都会创建一个 SocketChannel
====================================================================
read()表示该通道读就绪,可以从 Channel 中读取内容到缓冲区
表示该通道写就绪,可以将缓冲区中的内容写入 Channel。
l
============================================================================
使用 FileChannel 读数据到 Buffer 的示例:
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()
注意 buf.flip()
,首先读取数据到 Buffer,然后反转 Buffer,接着再从 Buffer 中读取数据。
==============================================================================
评论