Channel直译就是通道的意思,通道表示对数据源头和数据目标流经途径的抽象描述,和io中的InputStream和OutputStream类似。
首先借用网络上一张Channel的类图:
从channel的类层次结构来看在接口层面有区分读和写两种操作(ReadableByteChannel和WritableByteChannel),这点类似InputStream和OutputStream。但在实现类FileChannel和SocketChannel都实现了读写的接口,也就是既可以从通道中读取数据,又可以写数据到通道,这和io中单向的流是不同的,即nio中的通道是可以双向读写。
从类图中也可以看到nio中几个重要的通道实现:
FileChannel, SocketChannel,ServerSocketChannel, DatagramChannel。
1. FileChannel
文件的读写通道。可从现有的 FileInputStream 、 FileOutputStream 或 RandomAccessFile 对象获得文件通道,方法是调用该对象的 getChannel 方法,这会返回一个连接到相同底层文件的文件通道。
文件通道的状态与其 getChannel 返回该通道的对象密切相关。
在各种情况下指定要求“允许读取操作”、“允许写入操作”或“允许读取和写入操作”的某个实例。
通过 FileInputStream 实例的 getChannel 方法所获得的通道将允许进行读取操作。
通过 FileOutputStream 实例的 getChannel 方法所获得的通道将允许进行写入操作。
如果使用模式 "r" 创建 RandomAccessFile 实例,则通过该实例的 getChannel 方法所获得的通道将允许进行读取操作,如果使用模式 "rw" 创建实例,则获得的通道将允许进行读取和写入操作。
FileInputStream fi = new FileInputStream(infile); FileOutputStream fo = new FileOutputStream(outfile); FileChannel fiChannel = fi.getChannel(); FileChannel foChannel = fo.getChannel(); ByteBuffer buffer = ByteBuffer.allocate(1024); while (fiChannel.read(buffer) != -1) { buffer.flip(); foChannel.write(buffer); buffer.clear(); } RandomAccessFile raf = new RandomAccessFile(fileName , "rw"); FileChannel fc = raf.getChannel(); MappedByteBuffer mbb = fc.map(FileChannel.MapMode.READ_WRITE, 0, 1024); mbb.put(0, (byte) 97); mbb.put(1023, (byte) 122);
2. SocketChannel 和 ServerSocketChannel 是对原io包中的 Socket 和 ServerSocket 的可选择的无阻塞通道实现。从类结构来看都实现了SelectableChannel,结合selector实现无阻塞io,Selector为ServerSocketChannel 监控接收客户端连接就绪事件, 为 SocketChannel 监控连接服务器就绪, 读就绪和写就绪事件。
ServerSocketChannel稍微特殊,并没有实现ReadableByteChannel,专门负责监听传入的连接和创建新的 SocketChannel对象.由于ServerSocketChannel没有bind( )方法,因此有必要取出对等的socket并使用它来绑定到一个端口以开始监听连接。
下面一个简单的例子是一阻塞等待请求连接,单线程处理的方式。无阻塞模式要结合Selector事件驱动模型使用。
ServerSocketChannel ssc = ServerSocketChannel.open(); ssc.socket().bind(new InetSocketAddress(port)); while(true){ SocketChannel socketChannel = serverSocketChannel.accept(); if(socketChannel != null){ //... } }
结合Selector使用的简单无阻塞模式:
selector = Selector.open(); ServerSocketChannel ssc = ServerSocketChannel.open(); ssc.configureBlocking(false); ssc.socket().bind(new InetSocketAddress(port)); ssc.register(selector, SelectionKey.OP_ACCEPT); while (true) { int selected = selector.select(); if (selected > 0) { Iterator<SelectionKey> selectedKeys = selector.selectedKeys().iterator(); while (selectedKeys.hasNext()) { SelectionKey key = selectedKeys.next(); if ((key.readyOps() & SelectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) { ServerSocketChannel ssc = (ServerSocketChannel) key.channel(); SocketChannel sc = ssc.accept(); sc.configureBlocking(false); sc.register(selector, SelectionKey.OP_READ); selectedKeys.remove(); } else if ((key.readyOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ) { SocketChannel sc = (SocketChannel) key.channel(); IoBuffer buf = IoBuffer.allocate(1024); int readBytes = 0; try { int ret; while ((ret = sc.read(buf.buf())) > 0) { readBytes += ret; if (!buf.hasRemaining()) { break; } } } catch (IOException e) { e.printStackTrace(); } finally { buf.flip(); } // 处理buf中的数据。。。 sc.register(selector, SelectionKey.OP_WRITE); selectedKeys.remove(); } else if ((key.readyOps() & SelectionKey.OP_WRITE) == SelectionKey.OP_WRITE) { SocketChannel sc = (SocketChannel) key.channel(); String writeInfo = "Server received success !"; sc.write(Charset.forName("UTF-8").encode(writeInfo)); sc.close(); key.cancel(); } } } }
3. DatagramChannel是一个能收发UDP包的通道。因为UDP是无连接的网络协议,所以不能像其它通道那样读取和写入,它发送和接收的是数据包。
相关推荐
Java NIO(New Input/Output)是Java标准库在JDK 1.4版本中引入的一个新特性,它提供了一种不同于传统IO流的高效I/O处理方式。NIO的核心概念包括通道(Channel)和缓冲区(Buffer),这两个组件使得数据以块的形式...
ByteBuffer的用法是Java NIO学习中的核心内容。 首先,我们了解下ByteBuffer的基本概念。ByteBuffer是一个字节缓冲区,可以存储字节序列。在NIO中,所有的数据读写都通过缓冲区进行,ByteBuffer与其他类型的Buffer...
### Java NIO 学习笔记 #### 一、概述 Java NIO (Non-Blocking IO,也称为 Java New IO),是 Java 对传统 IO 模型的一次重大改进,旨在提高程序处理大量并发连接的能力。NIO 的核心组件包括 Channels、Buffers 和 ...
Java NIO(New Input/Output)是Java标准库在JDK 1.4引入的一组新的I/O API,它提供了一种不同于传统IO的高效、非阻塞的I/O操作方式。NIO的核心概念包括Channel、Buffer和Selector,它们共同构建了一个与操作系统...
Java NIO,全称Non-Blocking Input/Output,是非阻塞式输入输出,它是Java从1.4版本开始引入的一种新的I/O模型,为Java程序员提供了处理I/O操作的新方式。NIO的主要特点是其能够使Java程序以更有效的方式处理I/O流,...
Java NIO库提供了多种实现,如`java.nio.channels`包下的各种Channel和Selector类,以及`java.nio`包下的Buffer类。 在学习NIO时,首先需要理解Channel、Buffer、Selector的基本概念和使用方法,然后通过实例来熟悉...
Java JDK 5是Java开发工具集的...在"java jdk 5学习笔记"中,你可能会找到这些特性的详细使用示例和实践教程,帮助你深入理解和应用这些知识。通过学习和实践,你可以提升自己的Java编程技能,更好地应对各种开发场景。
Java JDK 6学习笔记PPT版是一份专为初学者设计的教育资源,旨在全面解析Java编程语言的基础知识。这份资料基于J2SDK1.6,也就是我们常说的JDK1.6或JDK6.0,它包含了Java开发工具集的重要更新和改进。JDK6.0是Oracle...
Java JDK 5.0是Java开发工具包的一个重要版本,由Sun Microsystems(后被Oracle收购)于2004年发布。...通过阅读“良葛格Java JDK 5.0学习笔记”,读者可以系统地学习和掌握这些内容,进一步提升自己的Java编程技能。
Java公司培训经典学习笔记是针对Java编程语言进行深入学习的一份宝贵资料,涵盖了从基础到高级的诸多知识点,旨在帮助开发者提升技能,适应企业级项目开发的需求。以下将详细阐述这些笔记中的关键点: 1. **Java...
在IO流方面,NIO(New IO)在Java 5.0中被引入,提供了一种基于通道(Channel)和缓冲区(Buffer)的I/O模型,相比于传统的流模型,NIO具有更好的非阻塞和选择器特性,适合处理大量并发连接。 最后,JDK 5.0对日期...
《NIO学习笔记》 在Java编程领域,NIO(Non-blocking Input/Output,非阻塞I/O)是一种重要的I/O模型,与传统的BIO(Blocking I/O)相对应。NIO提供了一种新的方式来处理I/O操作,特别是在处理大量并发连接时,它的...
### Java学习笔记知识点总结 #### 一、JVM与内存管理 **1.1 JVM基本概念** - **JVM(Java Virtual Machine)**: Java虚拟机是执行Java字节码的虚拟机,它提供了运行Java程序所需的环境。 **1.2 线程** - **线程...
这份"Java-J2SE学习笔记"涵盖了Java编程语言的基础到高级特性,是深入理解Java编程的重要参考资料。以下是对笔记中可能包含的关键知识点的详细解释: 1. **Java语言基础**: - **数据类型**:包括基本类型(如int...
在这个“Java客户端服务器程序学习笔记”中,我们将深入探讨这一主题,包括如何设计、实现和交互这两个关键组件。 首先,客户端是用户与系统进行交互的部分,它发送请求到服务器并接收响应。服务器端则处理这些请求...
【凯达Java学习笔记】是一份综合性的Java编程学习资源,涵盖了从基础到进阶的各种主题,旨在帮助初学者和有经验的开发者提升Java技术能力。这份笔记可能包含了大量的实例代码、理论解释以及最佳实践,使得学习过程...
NIO的核心组件包括Channel、Buffer和Selector,它们极大地提升了多路复用IO的能力。 总结,Java IO流是Java平台中处理输入输出的基础,其丰富的类库和设计模式为开发者提供了灵活、高效的数据传输手段。通过深入...