Java NIO – Channel
在Java NIO中,Channel被用来I/O传输。Channel就像一个用来在Buffer和另外一头的实体(比如文件)之间传输数据的管道。一个Channel从一个实体里读取数据,并且把数据放到缓冲区(Buffer)里供别人(一般是我们的程序)消费,类似的,我们应该把数据写入到缓冲区里,然后Channel会把缓冲区里的数据传输到I/O的另一端。
Channel是Java NIO提供的用来访问原生的I/O机制的一种途径,我们在编程时应该使用Buffer来和Channel交互,所以,Channel更像是I/O两端实体的桥梁。所谓的Buffer,是Channel用来发送和接收数据的端点。
Channel的特点:
- 与传统的流(stream)相比,Channel是双向的,既可以写,也可以读。
- Channel可以把数据读进Buffer,也可以从Buffer里写数据。
- Channel可以执行异步(asynchronous)的读写操作。
- Channel可以支持阻塞(blocking)或者非阻塞(non-blocking)模式。
- 非阻塞的Channel不会使调用的线程进入sleep模式。
- 基于流的Channel(比如Socket)只能处于非阻塞模式。
- 数据可以在Channel和Channel之间传输,前提是其中一个Channel是FileChannel。
Java NIO中的Channel类
以下是Java NIO包中提供的两种主要的Channel类实现:
FileChannel
- 文件读写的Channel,不支持非阻塞模式。
SocketChannel
- 有三种Socket Channel类,包括SocketChannel, ServerSocketChannel and DatagramChannel。
- 可选择(selectable)的Channel,支持非阻塞模式。
一个Java NIO Channel的例子
下面这个例子从文本文件中读数据并且把内容打印到控制台中。我们使用RandomAccessFile和FileChannel把数据读取到ByteBuffer。我们读取512字节的数据到buffer,然后调用buffer的flip方法,使其准备好get操作。一旦我们把数据打印到控制台,我们调用buffer的clear方法,使其可以进行下一次读。如此,一直到文件的末尾。
package com.javapapers.java.nio;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class ChannelExample {
public static void main(String args[]) throws IOException {
RandomAccessFile file = new RandomAccessFile("temp.txt", "r");
FileChannel fileChannel = file.getChannel();
ByteBuffer byteBuffer = ByteBuffer.allocate(512);
while (fileChannel.read(byteBuffer) > 0) {
// flip the buffer to prepare for get operation
byteBuffer.flip();
while (byteBuffer.hasRemaining()) {
System.out.print((char) byteBuffer.get());
}
// clear the buffer ready for next sequence of read
byteBuffer.clear();
}
file.close();
}
}
下一篇,我们会详细看下Java NIO的Buffer和各种Channel类。
本文翻译自 javapapers文章 ,仅供参考和学习。