JAVA NIO 基础(一)

NIO很少公司在用,大多是在用neety了,感觉已经被遗弃了,这段时间,整理一下NIO相关方面的知识,结合自己做的小游戏,用它来介绍NIO如何使用,会介绍基础原理,主要以实例为主。

IO简单介绍:

IO,简单的说,就是把数据移进或移出缓冲区。JVMA进程执行IO操作,要求缓区被填满,就会间接调用系统命令read(),内核会向磁盘控制器发出命令,请求读取磁盘据,这一步由DMA完成。当磁盘控制器将缓冲区填满时,内核会把数据从内核缓冲区拷贝到IO进程,执行read调用时指定的缓冲区.如下图:


用户空间:常规进程所在的区域。JVM就在用户空间,在该区域执行的代码不能直接访问硬件设备。

内核空间:操作系统所在的区域。能与设备管理器通讯,控制用户进程的运行状态等。

NIO提供的新抽象:

ByteBuffer:字节缓冲区

属性介绍:

容量(Capacity)::缓冲区能够容纳的数据元素的最大数量。这一容量在缓冲区创建时被设定,并且永远不能被改变。
上限(Limit):缓冲区中现存元素的计数。通道会从position位置开始获取,取到limit位置结束.
位置(Position):元素索引。位置会自动由相应的get()和put()方法更新。
标记( MarK ) :一个备忘位置。

这四个属性遵循以下关系:

0 <= mark <= position <= limit <= capacity

例子:

		ByteBuffer bb = ByteBuffer.allocate(Short.SIZE / 8 + Integer.SIZE / 8);

		System.out.println("填充前:");
		System.out.println("capatity:" + bb.capacity());
		System.out.println("position:" + bb.position());
		System.out.println("limit:" + bb.limit());

		bb.putShort((short) 1);
		bb.putInt(2);

		System.out.println("填充后:");
		System.out.println("capatity:" + bb.capacity());
		System.out.println("position:" + bb.position());
		System.out.println("limit:" + bb.limit());
		
		/***
		 * 填充前:
		 *  capatity:6 
		 *  position:0 
		 *  limit:6 
		 *  
		 *  填充后:
		 *   capatity:6
		 *   position:6 
		 *   limit:6
		 */


方法介绍:

put()/get():存取。

        flip():翻转

compact():压缩

   下面是代码模拟:

		ByteBuffer bb = ByteBuffer.allocate(Short.SIZE / 8 + Integer.SIZE / 8);

		System.out.println("填充前:");
		System.out.println("capatity:" + bb.capacity());
		System.out.println("position:" + bb.position());
		System.out.println("limit:" + bb.limit());

		bb.putShort((short) 1);
		bb.putInt(2);

		System.out.println("填充后:");
		System.out.println("capatity:" + bb.capacity());
		System.out.println("position:" + bb.position());
		System.out.println("limit:" + bb.limit());
		
		// 将位置值重新设为0,通道就会从正确位置开始获取
		bb.flip();

		System.out.println("翻转后:");
		System.out.println("capatity:" + bb.capacity());
		System.out.println("position:" + bb.position());
		System.out.println("limit:" + bb.limit());

		/***
		 * 填充前: capatity:6 position:0 limit:6 填充后: capatity:6 position:6 limit:6
		 * 翻转后: capatity:6 position:0 limit:6
		 */

		bb.getShort();

		System.out.println("get后:");
		System.out.println("capatity:" + bb.capacity());
		System.out.println("position:" + bb.position());
		System.out.println("limit:" + bb.limit());

		// 有时,您可能只想从缓冲区中释放一部分数据,而不是全部,然后重新填充
		bb.compact();

		System.out.println("compact后:");
		System.out.println("capatity:" + bb.capacity());
		System.out.println("position:" + bb.position());
<p>		System.out.println("limit:" + bb.limit());</p>
		/***
		 * 填充前: capatity:6 position:0 limit:6
		 * 填充后: capatity:6 position:6 limit:6
		 * 翻转后: capatity:6 position:0 limit:6
		 * get后: capatity:6 position:2  limit:6 
		 * compact后: capatity:6 position:4 limit:6
		 */

Chnnel:通道

通道是双向的,可以读也可以写。常用的有SokcetChannel,ServerSocketChannel.

ServerSocketChannel:是一个基于通道的socket监听器.ServerSocketChannel没有bind( )方法,可以通过调用socket()方法来获取ServerSocket对象,用这个对象去绑定地址,然后ServerSocketChannel调用accept()方法等待连接。

SocketChannel:扮演客户端向服务器发起连接。open()方法会创建一个SocketChannel对象,调用connect()来将该socket通道连接。

Selector:选择器

选择器管理着被注册通道集合的信息和他们就绪的状态。通道是和选择器一起被注册的,并且使用选择器来更新通道的就绪状态.选择器用来管理通道。

SelectionKey:选择键

选择键封装了特定的通道与特定的选择器的注册关系.通道会调用register方法去注册选择器,并注册相应的选择键。通道和选择器的关系封装在选择键里.


这一篇就讲到这里,下 一篇将用到这些知识。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值