一:channel
用于 I/O 操作的连接。
通道表示到实体,如硬件设备、文件、网络套接字或可以执行一个或多个不同 I/O 操作(如读取或写入)的程序组件的开放的连接。
通道可处于打开或关闭状态。创建通道时它处于打开状态,一旦将其关闭,则保持关闭状态。一旦关闭了某个通道,试图对其调用 I/O 操作就会导致 ClosedChannelException
被抛出。通过调用通道的 isOpen
方法可测试通道是否处于打开状态。
正如扩展和实现此接口的各个接口和类规范中所描述的,一般情况下通道对于多线程的访问是安全的。
public interface Channelextends Closeable
二:channel 与流比较
Java NIO 的channel类似流,但是有不同,
既可以从通道中读取数据,又可以写数据到通道。但流的读写通常是单向的。
通道可以异步地读写。
通道中的数据总是要先读到一个Buffer,或者总是要从一个Buffer中写入。
正如上面所说,从通道读取数据到缓冲区,从缓冲区写入数据到通道。如下图所示:
JAVA NIO中的一些主要Channel的实现:
FileChannel : 用于读取、写入、映射和操作文件的通道。(多个并发线程可安全地使用文件通道。)
DatagramChannel : 针对面向数据报套接字的可选择通道。(数据报通道不是网络数据报套接字的完整抽象。)
SocketChannel : 针对面向流的连接套接字的可选择通道。(套接字通道不是连接网络套接字的完整抽象)
ServerSocketChannel :针对面向流的侦听套接字的可选择通道。(服务器套接字通道不是侦听网络套接字的完整抽象。)
即:
FileChannel 从文件中读写数据。
DatagramChannel 能通过UDP读写网络中的数据。
SocketChannel 能通过TCP读写网络中的数据。
ServerSocketChannel可以监听新进来的TCP连接,像Web服务器那样。对每一个新进来的连接都会创建一个SocketChannel。
基本的channel示例
下面是一个使用FileChannel读取数据到Buffer中的示例:
public class Test1Channel {
public static void main(String[] args) throws IOException {
// File file = new File("data/niodata.txt");
// RandomAccessFile aFile = new RandomAccessFile(file, "rw");
//创建从中读取和向其中写入(可选)的随机访问文件流
RandomAccessFile aFile = new RandomAccessFile("data/niodata.txt", "rw");
System.out.println(aFile.length()); // 返回此文件的长度。
//FileChannel:用于读取、写入、映射和操作文件的通道。
//从文件中读写数据。
FileChannel inChannel = aFile.getChannel();
//allocate(20) 分配一个新的字节缓冲区。
ByteBuffer buf = ByteBuffer.allocate(10);
// read(buf) 将字节序列从此通道读入给定的缓冲区。
int bytesRead = inChannel.read(buf);
while (bytesRead != -1) {
//System.out.println("Read " + bytesRead);
buf.flip().position(); // 反转缓冲区
//hasRemaining():告知在当前位置和限制之间是否还有元素。
while(buf.hasRemaining()){
System.out.print((char) buf.get()+ " ");
}
buf.clear(); // 清除此缓冲区。
bytesRead = inChannel.read(buf);
}
aFile.close();
}
}
注意:
public RandomAccessFile(String name,String mode):
mode 参数指定用以打开文件的访问模式。允许的值及其含意为:
值
含意
"r"
以只读方式打开。调用结果对象的任何 write 方法都将导致抛出
IOException
。"rw"
打开以便读取和写入。如果该文件尚不存在,则尝试创建该文件。
"rws"
打开以便读取和写入,对于 "rw",还要求对文件的内容或元数据的每个更新都同步写入到底层存储设备。
"rwd"
打开以便读取和写入,对于 "rw",还要求对文件内容的每个更新都同步写入到底层存储设备。