`
zhhphappy
  • 浏览: 120197 次
  • 性别: 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
分享到:
评论

相关推荐

    JavaNIO chm帮助文档

    Java NIO系列教程(二) Channel Java NIO系列教程(三) Buffer Java NIO系列教程(四) Scatter/Gather Java NIO系列教程(五) 通道之间的数据传输 Java NIO系列教程(六) Selector Java NIO系列教程(七) ...

    java NIO和java并发编程的书籍

    java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java NIO和java并发编程的书籍java...

    JAVA NIO 学习资料

    JAVA NIO学习资料JAVA NIO学习资料

    java nio入门学习,两个pdf

    java nio入门学习,两个pdfjava nio入门学习,两个pdf

    javaNIO学习笔记

    java NIO的基本知识点学习笔记,不包含具体代码

    Java NIO实战开发多人聊天室

    05-Java NIO-Channel-FileChannel详解(一).mp4 06-Java NIO-Channel-FileChannel详解(二).mp4 08-Java NIO-Channel-ServerSocketChannel.mp4 09-Java NIO-Channel-SocketChannel.mp4 10-Java NIO-Channel-...

    Java NIO英文高清原版

    Java NIO英文高清原版

    java NIO 视频教程

    Java NIO(New IO)是一个可以替代标准Java IO API的IO API(从Java 1.4开始),Java NIO提供了与标准IO不同的IO工作方式。 Java NIO: Channels and Buffers(通道和缓冲区) 标准的IO基于字节流和字符流进行操作的,...

    java nio 包读取超大数据文件

    Java nio 超大数据文件 超大数据文件Java nio 超大数据文件 超大数据文件Java nio 超大数据文件 超大数据文件Java nio 超大数据文件 超大数据文件Java nio 超大数据文件 超大数据文件Java nio 超大数据文件 超大数据...

    Java NIO 中文 Java NIO 中文 Java NIO 中文文档

    Java NIO 深入探讨了 1.4 版的 I/O 新特性,并告诉您如何使用这些特性来极大地提升您所写的 Java 代码的执行效率。这本小册子就程序员所面临的有代表性的 I/O 问题作了详尽阐述,并讲解了 如何才能充分利用新的 I/O ...

    java NIO.zip

    java NIO.zip

    java NIO 中文版

    讲解了 JavaIO 与 JAVA NIO区别,JAVA NIO设计理念,以及JDK中java NIO中语法的使用

    java nio 实现socket

    java nio 实现socketjava nio 实现socketjava nio 实现socketjava nio 实现socketjava nio 实现socket

    java学习笔记1(java io/nio)

    java学习笔记1(java io/nio)设计模式

    java网络编程NIO视频教程

    03-Java NIO-Channel-概述.mp4 04-Java NIO-Channel-FileChannel(介绍和示例).mp4 05-Java NIO-Channel-FileChannel详解(一).mp4 06-Java NIO-Channel-FileChannel详解(二).mp4 07-Java NIO-Channel-Socket通道-概述...

    java nio中文版

    java NIO是 java New IO 的简称,在 jdk1.4 里提供的新 api 。 Sun 官方标榜的特性如下: – 为所有的原始类型提供 (Buffer) 缓存支持。 – 字符集编码解码解决方案。 – Channel :一个新的原始 I/O 抽象。 – 支持...

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

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

    java NIO学习系列 笔记

    Contents: 1 核心概念以及基本读写 2 缓冲区的实现机制 3 连网与异步IO 4 分散和聚集IO 5 文件锁定

    java_nio学习文档

    java_nio学习文档

    Java Nio selector例程

    java侧起server(NioUdpServer1.java),基于Java Nio的selector 阻塞等候,一个android app(NioUdpClient1文件夹)和一个java程序(UI.java)作为两个client分别向该server发数据,server收到后分别打印收到的消息...

Global site tag (gtag.js) - Google Analytics