注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

0与1构筑世界,程序员创造时代

软件架构设计 Java编程

 
 
 

日志

 
 

NIO - 入门篇(笔记)  

2008-10-21 17:29:01|  分类: Java |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

比较

Old IO  - 用以字节为单位进行操作。
    优点:使用简单。
    缺点:速度慢。
    流是单向的,InputStream完成读,OutputStream完成写。

NIO 块 - 以数据为单位进行操作。
    优点:速度快。
    缺点:使用比流要稍复杂,编程不像流那样的优雅。
    通道是双向的。

NIO - 入门篇(笔记) - 傲风 - 宝剑锋从磨砺出 梅花香自苦寒来提示:在JDK1.4开始引入NIO类库(java.nio.*)后,对原来的java.io.* 以NIO为基础进行了修改,因此速度上会更快。


NIO概念

Bufferr (缓冲区):用数组实现的缓存数据的对象。
Channel (通道):也可以称之为管道。可以想像成流水的水管,水就是我们的数据。

下面两个图是NIO读/写数据时的示意图:

NIO - 入门篇(笔记) - 傲风 - 宝剑锋从磨砺出 梅花香自苦寒来
图1 - NIO读数据示意图


NIO - 入门篇(笔记) - 傲风 - 宝剑锋从磨砺出 梅花香自苦寒来
图2 - NIO写数据示意图


Buffer的三个状态变量

position(位置点)。跟踪当前已经读/写了多少数据,例如:在读取数据时,position=3,表示已经从Buffer读取三个元素值,当前指针指向第四个元素(即下一个读取的元素的位置);在写数据时,position=3,表示已经向Buffer写入了三个元素,指针指向第四个元素的位置(即下一个写入元素的位置)。
  • limit(限制值)。指定缓冲区允许读取/写入多少无素,默认情况下 limit=capacity。
  • capacity(容量)。
关系:position <= limit <= capacity

例:
1)定义一个容量为9的Buffer:ByteBuffer buffer = new ByteBuffer(9);

NIO - 入门篇(笔记) - 傲风 - 宝剑锋从磨砺出 梅花香自苦寒来
图 3 - 初始化状态下的Buffer

2)向Buffer写入两个元素:buffer.put(x); buffer.put(y);
NIO - 入门篇(笔记) - 傲风 - 宝剑锋从磨砺出 梅花香自苦寒来
图4 - 写入两个元素后的Buffer

3)执行flip()方法:buffer.flip();
将limit设置为position,然后将position设置为 0。如果已定义了标记,则丢弃该标记。

NIO - 入门篇(笔记) - 傲风 - 宝剑锋从磨砺出 梅花香自苦寒来
图5 - 执行flip()方法后的Buffer

4)执行clear()方法:buffer.clear();
注意:clear()方法不能实际清除缓冲区中的数据。只是将position设置为 0,将limint设置为容量,并丢弃标记。
NIO - 入门篇(笔记) - 傲风 - 宝剑锋从磨砺出 梅花香自苦寒来
图6 - 执行clear()方法后的Buffer


完整示例代码:
ByteBuffer buff = ByteBuffer.allocate(9);  // position=0, limit=9, capacity=9
buff.put((byte'a')   // position=1, limit=9, capacity=9
    .put((byte'b');  // position=2, limit=9, capacity=9
buff.flip();   // position=0, limit=2, capacity=9
buff.clear();  // position=0, limit=9, capacity=9
buff = null;

Buffer的分配包装与分片

缓冲区既可以直接生成,也可以包装一个字节数组获得。
示例代码:
 /*
 * 先分配内存,再赋值。
 */
ByteBuffer buff = ByteBuffer.allocate(9);
for (int i = 0; i < buff.capacity(); i++) {
   buff.put((bytei);
}// 到此buff的内容为 [0, 1, 2, 3, 4, 5, 6, 7, 8]

/*
 * 直接将一个数组包装成缓冲区。
 */
byte[] b = new byte[]{012345678};
ByteBuffer buff2 = ByteBuffer.wrap(b)// 到此buff2的内容为 [0, 1, 2, 3, 4, 5, 6, 7, 8]

/*
 * 分片操作。
 */
buff2.position(2);
buff2.limit(6);
ByteBuffer slice = buff2.slice();
 
b[2*= 11// buff2 和 slice 的内容都同时跟随改变,因为他们是共享一块内存区。
slice.put(1(byte) (((intslice.get(1)) 11))// buff2 和 slice 的内容都同时跟随改变,因为他们是共享一块内存区。


<正文结束>
文章声明


作者:傲风(aofengblog@163.com)       编写时间:2008年10月21日

网址:http://aofengblog.blog.163.com

作者保留所有权利,转载请保留文章全部内容或者说明原作者和转载地址!

  评论这张
 
阅读(1551)| 评论(4)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017