`
zhhphappy
  • 浏览: 121395 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

java nio channel 学习笔记

 
阅读更多

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是无连接的网络协议,所以不能像其它通道那样读取和写入,它发送和接收的是数据包。

 

  • 大小: 152.5 KB
分享到:
评论

相关推荐

    java NIO学习系列 笔记

    Java NIO(New Input/Output)是Java标准库在JDK 1.4版本中引入的一个新特性,它提供了一种不同于传统IO流的高效I/O处理方式。NIO的核心概念包括通道(Channel)和缓冲区(Buffer),这两个组件使得数据以块的形式...

    Java NIO学习笔记——ByteBuffer用法

    ByteBuffer的用法是Java NIO学习中的核心内容。 首先,我们了解下ByteBuffer的基本概念。ByteBuffer是一个字节缓冲区,可以存储字节序列。在NIO中,所有的数据读写都通过缓冲区进行,ByteBuffer与其他类型的Buffer...

    javaNIO学习笔记

    ### Java NIO 学习笔记 #### 一、概述 Java NIO (Non-Blocking IO,也称为 Java New IO),是 Java 对传统 IO 模型的一次重大改进,旨在提高程序处理大量并发连接的能力。NIO 的核心组件包括 Channels、Buffers 和 ...

    JAVA NIO学习笔记.docx

    Java NIO(New Input/Output)是Java标准库在JDK 1.4引入的一组新的I/O API,它提供了一种不同于传统IO的高效、非阻塞的I/O操作方式。NIO的核心概念包括Channel、Buffer和Selector,它们共同构建了一个与操作系统...

    javaNIO学习笔记(csdn)————程序.pdf

    Java NIO,全称Non-Blocking Input/Output,是非阻塞式输入输出,它是Java从1.4版本开始引入的一种新的I/O模型,为Java程序员提供了处理I/O操作的新方式。NIO的主要特点是其能够使Java程序以更有效的方式处理I/O流,...

    nio demo for nio学习笔记(体系结构以及模块介绍)

    Java NIO库提供了多种实现,如`java.nio.channels`包下的各种Channel和Selector类,以及`java.nio`包下的Buffer类。 在学习NIO时,首先需要理解Channel、Buffer、Selector的基本概念和使用方法,然后通过实例来熟悉...

    java jdk 5学习笔记

    Java JDK 5是Java开发工具集的...在"java jdk 5学习笔记"中,你可能会找到这些特性的详细使用示例和实践教程,帮助你深入理解和应用这些知识。通过学习和实践,你可以提升自己的Java编程技能,更好地应对各种开发场景。

    Java JDK 6学习笔记PPT版

    Java JDK 6学习笔记PPT版是一份专为初学者设计的教育资源,旨在全面解析Java编程语言的基础知识。这份资料基于J2SDK1.6,也就是我们常说的JDK1.6或JDK6.0,它包含了Java开发工具集的重要更新和改进。JDK6.0是Oracle...

    良葛格Java JDK 5[1].0学习笔记

    Java JDK 5.0是Java开发工具包的一个重要版本,由Sun Microsystems(后被Oracle收购)于2004年发布。...通过阅读“良葛格Java JDK 5.0学习笔记”,读者可以系统地学习和掌握这些内容,进一步提升自己的Java编程技能。

    Java公司培训经典学习笔记

    Java公司培训经典学习笔记是针对Java编程语言进行深入学习的一份宝贵资料,涵盖了从基础到高级的诸多知识点,旨在帮助开发者提升技能,适应企业级项目开发的需求。以下将详细阐述这些笔记中的关键点: 1. **Java...

    良葛格Java JDK 5.0学习笔记

    在IO流方面,NIO(New IO)在Java 5.0中被引入,提供了一种基于通道(Channel)和缓冲区(Buffer)的I/O模型,相比于传统的流模型,NIO具有更好的非阻塞和选择器特性,适合处理大量并发连接。 最后,JDK 5.0对日期...

    NIO学习笔记

    《NIO学习笔记》 在Java编程领域,NIO(Non-blocking Input/Output,非阻塞I/O)是一种重要的I/O模型,与传统的BIO(Blocking I/O)相对应。NIO提供了一种新的方式来处理I/O操作,特别是在处理大量并发连接时,它的...

    阿里P8 架构师整理Java学习笔记.pdf

    ### Java学习笔记知识点总结 #### 一、JVM与内存管理 **1.1 JVM基本概念** - **JVM(Java Virtual Machine)**: Java虚拟机是执行Java字节码的虚拟机,它提供了运行Java程序所需的环境。 **1.2 线程** - **线程...

    Java-J2SE学习笔记

    这份"Java-J2SE学习笔记"涵盖了Java编程语言的基础到高级特性,是深入理解Java编程的重要参考资料。以下是对笔记中可能包含的关键知识点的详细解释: 1. **Java语言基础**: - **数据类型**:包括基本类型(如int...

    Java 客户端服务器程序 学习笔记

    在这个“Java客户端服务器程序学习笔记”中,我们将深入探讨这一主题,包括如何设计、实现和交互这两个关键组件。 首先,客户端是用户与系统进行交互的部分,它发送请求到服务器并接收响应。服务器端则处理这些请求...

    凯达Java学习笔记

    【凯达Java学习笔记】是一份综合性的Java编程学习资源,涵盖了从基础到进阶的各种主题,旨在帮助初学者和有经验的开发者提升Java技术能力。这份笔记可能包含了大量的实例代码、理论解释以及最佳实践,使得学习过程...

    java io流学习笔记1

    NIO的核心组件包括Channel、Buffer和Selector,它们极大地提升了多路复用IO的能力。 总结,Java IO流是Java平台中处理输入输出的基础,其丰富的类库和设计模式为开发者提供了灵活、高效的数据传输手段。通过深入...

Global site tag (gtag.js) - Google Analytics