<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>wufan0023</title>
    <description>java 程序员
</description>
    <link>http://wufan0023.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
          <item>
        <title>仿google密码评分规则[z]</title>
        <author>wufan0023</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://wufan0023.javaeye.com">wufan0023</a>&nbsp;
                    链接：<a href="http://wufan0023.javaeye.com/blog/200116" style="color:red;">http://wufan0023.javaeye.com/blog/200116</a>&nbsp;
          发表时间: 2008年06月04日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>一、密码长度:</p>
<ul>
<li>5 分: 小于等于 4 个字符 </li>
<li>10 分: 5 到 7 字符 </li>
<li>25 分: 大于等于 8 个字符 </li>
</ul>
<p>二、字母:</p>
<ul>
<li>0 分: 没有字母 </li>
<li>10 分: 全都是小（大）写字母 </li>
<li>20 分: 大小写混合字母 </li>
</ul>
<p>三、数字:</p>
<ul>
<li>0 分: 没有数字 </li>
<li>10 分: 1 个数字 </li>
<li>20 分: 大于等于 3 个数字 </li>
</ul>
<p>四、符号:</p>
<ul>
<li>0 分: 没有符号 </li>
<li>10 分: 1 个符号 </li>
<li>25 分: 大于 1 个符号 </li>
</ul>
<p>五、奖励:</p>
<ul>
<li>2 分: 字母和数字 </li>
<li>3 分: 字母、数字和符号 </li>
<li>5 分: 大小写字母、数字和符号 </li>
</ul>
<p><strong>最后的评分标准:</strong></p>
<ul>
<li>&gt;= 90: 非常安全 </li>
<li>&gt;= 80: 安全（Secure） </li>
<li>&gt;= 70: 非常强 </li>
<li>&gt;= 60: 强（Strong） </li>
<li>&gt;= 50: 一般（Average） </li>
<li>&gt;= 25: 弱（Weak） </li>
<li>&gt;= 0: 非常弱 </li>
</ul>
          <br/><br/>
          <span style="color:red;">
            <a href="http://wufan0023.javaeye.com/blog/200116#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 04 Jun 2008 15:40:31 +0800</pubDate>
        <link>http://wufan0023.javaeye.com/blog/200116</link>
        <guid>http://wufan0023.javaeye.com/blog/200116</guid>
      </item>
          <item>
        <title>Java NIO API详解 (II)[z]</title>
        <author>wufan0023</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://wufan0023.javaeye.com">wufan0023</a>&nbsp;
                    链接：<a href="http://wufan0023.javaeye.com/blog/198722" style="color:red;">http://wufan0023.javaeye.com/blog/198722</a>&nbsp;
          发表时间: 2008年05月30日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><span style="font-family: Arial;"><span style="font-size: small;"><strong>SelectableChannel</strong></span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small;"><span><span style="text-decoration: underline;">这个抽象类是所有支持异步<span style="font-family: Arial;">IO</span>操作的<span style="font-family: Arial;">channel</span>（如<span style="font-family: Arial;">DatagramChannel</span>、<span style="font-family: Arial;">SocketChannel</span>）的父类。</span><span style="font-family: Arial;">SelectableChannel</span>可以注册到一个或多个<span style="font-family: Arial;">Selector</span>上以进行异步<span style="font-family: Arial;">IO</span>操作。</span><span style="font-family: Arial;"><span> </span></span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small;"><span><span style="font-family: Arial;">SelectableChannel</span><span style="background-color: #ffff00;">可以是<span style="font-family: Arial;">blocking</span>和<span style="font-family: Arial;">non-blocking</span>模式</span>（所有<span style="font-family: Arial;">channel</span>创建的时候都是<span style="font-family: Arial;">blocking</span>模式），只有<span style="font-family: Arial;">non-blocking</span>的<span style="font-family: Arial;">SelectableChannel</span>才可以参与异步<span style="font-family: Arial;">IO</span>操作。</span><span style="font-family: Arial;"><span> </span></span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small;"><span style="font-family: Arial;">SelectableChannel configureBlocking(boolean block)</span><span><span style="font-family: Arial;">&nbsp;&nbsp;--- </span>设置<span style="font-family: Arial;">blocking</span>模式。</span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small;"><span style="font-family: Arial;">boolean isBlocking()</span><span><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;---&nbsp; </span>返回<span style="font-family: Arial;">blocking</span>模式。</span><span style="font-family: Arial;"><span> </span></span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small;"><span>通过<span style="font-family: Arial;"><strong>register()</strong></span>方法，<span style="text-decoration: underline;"><span style="font-family: Arial;">SelectableChannel</span>可以注册到<span style="font-family: Arial;">Selector</span>上。</span></span><span style="font-family: Arial;"><span> </span></span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">int validOps()</span></p>
<p style="padding-left: 30px;"><span style="font-size: small;">返回一个<span style="font-family: Arial;">bit mask</span>，表示这个<span style="font-family: Arial;">channel</span>上支持的<span style="font-family: Arial;">IO</span>操作。当前在<span style="font-family: Arial;">SelectionKey</span>中，用静态常量定义了<span style="font-family: Arial;">4</span>种<span style="font-family: Arial;">IO</span>操作的<span style="font-family: Arial;">bit</span>值：<span style="font-family: Arial;">OP_ACCEPT</span>，<span style="font-family: Arial;">OP_CONNECT</span>，<span style="font-family: Arial;">OP_READ</span>和<span style="font-family: Arial;">OP_WRITE</span>。</span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">SelectionKey register(Selector sel, int ops)</span></p>
<p style="padding-left: 30px;"><span style="font-size: small;">将当前<span style="font-family: Arial;">channel</span>注册到一个<span style="font-family: Arial;">Selector</span>上并返回对应的<span style="font-family: Arial;">SelectionKey</span>。在这以后，通过调用<span style="font-family: Arial;">Selector</span>的<span style="font-family: Arial;">select()</span>函数就可以监控这个<span style="font-family: Arial;">channel</span>。<span style="font-family: Arial;">ops</span>这个参数是一个<span style="font-family: Arial;">bit mask</span>，代表了需要监控的<span style="font-family: Arial;">IO</span>操作。</span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">SelectionKey register(Selector sel, int ops, Object att)</span></p>
<p style="padding-left: 30px;"><span style="font-size: small;">这个函数和上一个的意义一样，多出来的<span style="font-family: Arial;">att</span>参数会作为<span style="font-family: Arial;">attachment</span>被存放在返回的<span style="font-family: Arial;">SelectionKey</span>中，这在需要存放一些<span style="font-family: Arial;">session state</span>的时候非常有用。</span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">boolean isRegistered()</span></p>
<p style="padding-left: 30px;"><span style="font-size: small;"><span><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>该<span style="font-family: Arial;">channel</span>是否已注册在一个或多个<span style="font-family: Arial;">Selector</span>上。</span><span style="font-family: Arial;"><span> </span></span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small;"><span><span style="font-family: Arial;">SelectableChannel</span>还提供了得到对应<span style="font-family: Arial;">SelectionKey</span>的方法：</span><span style="font-family: Arial;"><span> </span></span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">SelectionKey keyFor(Selector sel)</span></p>
<p style="padding-left: 30px;"><span style="font-size: small;"><span>返回该<span style="font-family: Arial;">channe</span>在<span style="font-family: Arial;">Selector</span>上的注册关系所对应的<span style="font-family: Arial;">SelectionKey</span>。若无注册关系，返回<span style="font-family: Arial;">null</span>。</span><span style="font-family: Arial;"><span> </span></span></span></p>
<p><strong><span style="font-family: Arial;"><span style="font-size: small;">Selector</span></span></strong></p>
<p style="padding-left: 30px;"><span style="font-size: small;"><span><span style="text-decoration: underline;"><span style="font-family: Arial;">Selector</span>可以同时监控多个<span style="font-family: Arial;">SelectableChannel</span>的<span style="font-family: Arial;">IO</span>状况，是异步<span style="font-family: Arial;">IO</span>的核心。</span></span><span style="font-family: Arial;"><span> </span></span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">Selector open()</span></p>
<p style="padding-left: 30px;"><span style="font-size: small;"><span><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Selector</span>的一个静态方法，用于创建实例。</span><span style="font-family: Arial;"><span> </span></span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small;">在一个<span style="font-family: Arial;">Selector</span>中，有<span style="font-family: Arial;">3</span>个<span style="font-family: Arial;">SelectionKey</span>的集合：</span></p>
<p style="padding-left: 30px;"><span><span style="font-size: small;"><span style="font-family: Arial;">1．</span> <span style="font-family: Arial;"><strong>key set</strong></span>代表了所有注册在这个<span style="font-family: Arial;">Selector</span>上的<span style="font-family: Arial;">channel</span>，这个集合可以通过<span style="font-family: Arial;">keys()</span>方法拿到。</span></span></p>
<p style="padding-left: 30px;"><span><span style="font-size: small;"><span style="font-family: Arial;">2．</span> <span style="font-family: Arial;"><strong>Selected-key</strong> set</span>代表了所有通过<span style="font-family: Arial;">select()</span>方法监测到可以进行<span style="font-family: Arial;">IO</span>操作的<span style="font-family: Arial;">channel</span>，这个集合可以通过<span style="font-family: Arial;">selectedKeys()</span>拿到。</span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small;"><span><span style="font-family: Arial;">3．</span> <span style="font-family: Arial;"><strong>Cancelled-key set</strong></span>代表了已经<span style="font-family: Arial;">cancel</span>了注册关系的<span style="font-family: Arial;">channel</span>，在下一个<span style="font-family: Arial;">select()</span>操作中，这些<span style="font-family: Arial;">channel</span>对应的<span style="font-family: Arial;">SelectionKey</span>会从<span style="font-family: Arial;">key set</span>和<span style="font-family: Arial;">cancelled-key set</span>中移走。这个集合无法直接访问。</span><span style="font-family: Arial;"><span> </span></span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small;"><span>以下是<span style="font-family: Arial;">select()</span>相关方法的说明：</span><span style="font-family: Arial;"><span> </span></span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">int select()</span></p>
<p style="padding-left: 30px;"><span style="font-size: small;">监控所有注册的<span style="font-family: Arial;">channel</span>，当其中有注册的<span style="font-family: Arial;">IO</span>操作可以进行时，该函数返回，并将对应的<span style="font-family: Arial;">SelectionKey</span>加入<span style="font-family: Arial;">selected-key set</span>。</span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">int select(long timeout)</span></p>
<p style="padding-left: 30px;"><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>可以设置超时的<span style="font-family: Arial;">select()</span>操作。</span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">int selectNow()</span></p>
<p style="padding-left: 30px;"><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>进行一个立即返回的<span style="font-family: Arial;">select()</span>操作。</span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">Selector wakeup()</span></p>
<p style="padding-left: 30px;"><span style="font-size: small;"><span><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>使一个还未返回的<span style="font-family: Arial;">select()</span>操作立刻返回。</span><span style="font-family: Arial;"><span> </span></span></span></p>
<p><strong><span style="font-family: Arial;"><span style="font-size: small;">SelectionKey</span></span></strong></p>
<p style="padding-left: 30px;"><span style="font-size: small;"><span>代表了<span style="font-family: Arial;">Selector</span>和<span style="font-family: Arial;">SelectableChannel</span>的注册关系。</span><span style="font-family: Arial;"><span> </span></span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small;"><span><span style="font-family: Arial;">Selector</span>定义了<span style="font-family: Arial;">4</span>个静态常量来表示<span style="font-family: Arial;">4</span>种<span style="font-family: Arial;">IO</span>操作，这些常量可以进行位操作组合成一个<span style="font-family: Arial;">bit mask</span>。</span><span style="font-family: Arial;"><span> </span></span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small;"><span style="font-family: Arial;">int OP_ACCEPT</span> </span></p>
<p style="padding-left: 30px;"><span style="font-size: small;">有新的网络连接可以<span style="font-family: Arial;">accept</span>，<span style="color: #000000; font-family: Arial;">ServerSocketChannel</span>支持这一异步<span style="font-family: Arial;">IO</span>。</span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">int OP_CONNECT</span></p>
<p style="padding-left: 30px;"><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>代表连接已经建立（或出错），<span style="font-family: Arial;">SocketChannel</span>支持这一异步<span style="font-family: Arial;">IO</span>。</span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">int OP_READ</span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">int OP_WRITE</span></p>
<p style="padding-left: 30px;"><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>代表了读、写操作。</span></span></p>
<p style="padding-left: 30px;">&nbsp;</p>
<p style="padding-left: 30px;"><span style="font-size: small;">以下是其主要方法：</span></p>
<p style="padding-left: 30px;">&nbsp;</p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">Object attachment()</span></p>
<p style="padding-left: 30px;"><span style="font-size: small;">返回<span style="font-family: Arial;">SelectionKey</span>的<span style="font-family: Arial;">attachment</span>，<span style="font-family: Arial;">attachment</span>可以在注册<span style="font-family: Arial;">channel</span>的时候指定。</span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">Object attach(Object ob)</span></p>
<p style="padding-left: 30px;"><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>设置<span style="font-family: Arial;">SelectionKey</span>的<span style="font-family: Arial;">attachment</span>。</span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">SelectableChannel channel()</span></p>
<p style="padding-left: 30px;"><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>返回该<span style="font-family: Arial;">SelectionKey</span>对应的<span style="font-family: Arial;">channel</span>。</span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">Selector selector()</span></p>
<p style="padding-left: 30px;"><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>返回该<span style="font-family: Arial;">SelectionKey</span>对应的<span style="font-family: Arial;">Selector</span>。</span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">void cancel()</span></p>
<p style="padding-left: 30px;"><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cancel</span>这个<span style="font-family: Arial;">SelectionKey</span>所对应的注册关系。</span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">int interestOps()</span></p>
<p style="padding-left: 30px;"><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>返回代表需要<span style="font-family: Arial;">Selector</span>监控的<span style="font-family: Arial;">IO</span>操作的<span style="font-family: Arial;">bit mask</span>。</span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">SelectionKey interestOps(int ops)</span></p>
<p style="padding-left: 30px;"><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>设置<span style="font-family: Arial;">interestOps</span>。</span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">int readyOps()</span></p>
<p style="padding-left: 30px;"><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>返回一个<span style="font-family: Arial;">bit mask</span>，代表在相应<span style="font-family: Arial;">channel</span>上可以进行的<span style="font-family: Arial;">IO</span>操作。</span></span></p>
<p style="padding-left: 30px;">&nbsp;</p>
<p><strong><span style="font-family: Arial;"><span style="font-size: small;">ServerSocketChannel</span></span></strong></p>
<p style="padding-left: 30px;"><span><span style="font-size: small;">支持异步操作，对应于<span style="font-family: Arial;">java.net.ServerSocket</span>这个类，提供了<span style="font-family: Arial;">TCP</span></span><a href="http://net.rdxx.com/Knowledge/Protocol/" target="_blank"><span style="font-size: small; color: #3080cb;">协议</span></a><span style="font-size: small;"><span style="font-family: Arial;">IO</span>接口，支持<span style="font-family: Arial;">OP_ACCEPT</span>操作。</span></span></p>
<p style="padding-left: 30px;">&nbsp;</p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">ServerSocket socket()</span></p>
<p style="padding-left: 30px;"><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>返回对应的<span style="font-family: Arial;">ServerSocket</span>对象。</span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">SocketChannel accept()</span></p>
<p style="padding-left: 30px;"><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>接受一个连接，返回代表这个连接的<span style="font-family: Arial;">SocketChannel</span>对象。</span></span></p>
<p style="padding-left: 30px;">&nbsp;</p>
<p><strong><span style="font-family: Arial;"><span style="font-size: small;">SocketChannel</span></span></strong></p>
<p style="padding-left: 30px;"><span style="font-size: small;">支持异步操作，对应于<span style="font-family: Arial;">java.net.Socket</span>这个类，提供了<span style="font-family: Arial;">TCP</span>协议<span style="font-family: Arial;">IO</span>接口，支持<span style="font-family: Arial;">OP_CONNECT</span>，<span style="font-family: Arial;">OP_READ</span>和<span style="font-family: Arial;">OP_WRITE</span>操作。这个类还实现了<span style="font-family: Arial;">ByteChannel</span>，<span style="font-family: Arial;">ScatteringByteChannel</span>和<span style="font-family: Arial;">GatheringByteChannel</span>接口。</span></p>
<p style="padding-left: 30px;"><span><span style="font-size: small;"><span style="font-family: Arial;">DatagramChannel</span>和这个类比较相似，其对应于<span style="font-family: Arial;">java.net.DatagramSocket</span>，提供了<span style="font-family: Arial;">UDP</span>协议<span style="font-family: Arial;">IO</span>接口。</span></span></p>
<p style="padding-left: 30px;">&nbsp;</p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">Socket socket()</span></p>
<p style="padding-left: 30px;"><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>返回对应的<span style="font-family: Arial;">Socket</span>对象。</span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">boolean connect(SocketAddress remote)</span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">boolean finishConnect()</span></p>
<p style="padding-left: 30px;"><span><span style="font-size: small;"><span style="font-family: Arial;">connect()</span>进行一个连接操作。如果当前<span style="font-family: Arial;">SocketChannel</span>是<span style="font-family: Arial;">blocking</span>模式，这个函数会等到连接操作完成或错误发生才返回。如果当前<span style="font-family: Arial;">SocketChannel</span>是<span style="font-family: Arial;">non-blocking</span>模式，函数在连接能立刻被建立时返回<span style="font-family: Arial;">true</span>，否则函数返回<span style="font-family: Arial;">false</span>，应用程序需要在以后用<span style="font-family: Arial;">finishConnect()</span>方法来完成连接操作。</span></span></p>
<p>&nbsp;</p>
<p><strong><span style="font-family: Arial;"><span style="font-size: small;">Pipe</span></span></strong></p>
<p style="padding-left: 30px;"><span style="font-size: small;">包含了一个读和一个写的<span style="font-family: Arial;">channel(Pipe.SourceChannel</span>和<span style="font-family: Arial;">Pipe.SinkChannel)</span>，这对<span style="font-family: Arial;">channel</span>可以用于进程中的通讯。</span></p>
<p>&nbsp;</p>
<p><strong><span style="font-family: Arial;"><span style="font-size: small;">FileChannel</span></span></strong></p>
<p style="padding-left: 30px;"><span style="font-size: small;">用于对文件的读、写、映射、锁定等操作。和映射操作相关的类有<span style="font-family: Arial;">FileChannel.MapMode</span>，和锁定操作相关的类有<span style="font-family: Arial;">FileLock</span>。值得注意的是<span style="font-family: Arial;">FileChannel</span>并不支持异步操作。</span></p>
<p>&nbsp;</p>
<p><strong><span style="font-family: Arial;"><span style="font-size: small;">Channels</span></span></strong></p>
<p style="padding-left: 30px;"><span style="font-size: small;">这个类提供了一系列<span style="font-family: Arial;">static</span>方法来支持<span style="font-family: Arial;">stream</span>类和<span style="font-family: Arial;">channel</span>类之间的互操作。这些方法可以将<span style="font-family: Arial;">channel</span>类包装为<span style="font-family: Arial;">stream</span>类，比如，将<span style="font-family: Arial;">ReadableByteChannel</span>包装为<span style="font-family: Arial;">InputStream</span>或<span style="font-family: Arial;">Reader</span>；也可以将<span style="font-family: Arial;">stream</span>类包装为<span style="font-family: Arial;">channel</span>类，比如，将<span style="font-family: Arial;">OutputStream</span>包装为<span style="font-family: Arial;">WritableByteChannel</span>。</span></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span style="font-family: Arial;"><span style="font-size: small;">Package java.nio.charset</span></span></p>
<p><span style="font-size: small;">这个包定义了<span style="font-family: Arial;">Charset</span>及相应的<span style="font-family: Arial;">encoder</span>和<span style="font-family: Arial;">decoder</span>。下面这张<span style="color: #3080cb; font-family: Arial;"><a href="http://dev.rdxx.com/SoftProject/UML/" target="_blank">UML</a></span>类图描述了这个包中类的关系，可以将其中<span style="font-family: Arial;">Charset</span>，<span style="font-family: Arial;">CharsetDecoder</span>和<span style="font-family: Arial;">CharsetEncoder</span>理解成一个<span style="font-family: Arial;">Abstract Factory</span>模式的实现：</span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<div>
<p style="text-align: center;"><span style="font-size: small;"><img class="blogimg" src="http://hiphotos.baidu.com/yaolihui/pic/item/d6efb3549e67030c3a293599.jpg" border="0" alt="" /></span></p>
<p><strong><span style="font-family: Arial;"><span style="font-size: small;">Charset</span></span></strong></p>
<p style="padding-left: 30px; text-align: left;"><span style="font-size: small;"><span>代表了一个字符集，同时提供了<span style="font-family: Arial;">factory method</span>来构建相应的<span style="font-family: Arial;">CharsetDecoder</span>和<span style="font-family: Arial;">CharsetEncoder</span>。</span><span style="font-family: Arial;"><span> </span></span></span></p>
<p style="padding-left: 30px; text-align: left;"><span style="font-size: small;"><span><span style="font-family: Arial;">Charset</span>提供了以下<span style="font-family: Arial;">static</span>的方法：</span><span style="font-family: Arial;"><span> </span></span></span></p>
<p style="padding-left: 30px; text-align: left;"><span style="font-size: small; font-family: Arial;">SortedMap availableCharsets()</span></p>
<p style="padding-left: 30px; text-align: left;"><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>返回当前系统支持的所有<span style="font-family: Arial;">Charset</span>对象，用<span style="font-family: Arial;">charset</span>的名字作为<span style="font-family: Arial;">set</span>的<span style="font-family: Arial;">key</span>。</span></span></p>
<p style="padding-left: 30px; text-align: left;"><span style="font-size: small; font-family: Arial;">boolean isSupported(String charsetName)</span></p>
<p style="padding-left: 30px; text-align: left;"><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>判断该名字对应的字符集是否被当前系统支持。</span></span></p>
<p style="padding-left: 30px; text-align: left;"><span style="font-size: small; font-family: Arial;">Charset forName(String charsetName)</span></p>
<p style="padding-left: 30px; text-align: left;"><span style="font-size: small;"><span><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>返回该名字对应的<span style="font-family: Arial;">Charset</span>对象。</span><span style="font-family: Arial;"><span> </span></span></span></p>
<p style="padding-left: 30px; text-align: left;"><span style="font-size: small;"><span><span style="font-family: Arial;">Charset</span>中比较重要的方法有：</span><span style="font-family: Arial;"><span> </span></span></span></p>
<p style="padding-left: 30px; text-align: left;"><span style="font-size: small; font-family: Arial;">String name()</span></p>
<p style="padding-left: 30px; text-align: left;"><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>返回该字符集的规范名。</span></span></p>
<p style="padding-left: 30px; text-align: left;"><span style="font-size: small; font-family: Arial;">Set aliases()</span></p>
<p style="padding-left: 30px; text-align: left;"><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>返回该字符集的所有别名。</span></span></p>
<p style="padding-left: 30px; text-align: left;"><span style="font-size: small; font-family: Arial;">CharsetDecoder newDecoder()</span></p>
<p style="padding-left: 30px; text-align: left;"><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>创建一个对应于这个<span style="font-family: Arial;">Charset</span>的<span style="font-family: Arial;">decoder</span>。</span></span></p>
<p style="padding-left: 30px; text-align: left;"><span style="font-size: small; font-family: Arial;">CharsetEncoder newEncoder()</span></p>
<p style="padding-left: 30px; text-align: left;"><span style="font-size: small;"><span><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>创建一个对应于这个<span style="font-family: Arial;">Charset</span>的<span style="font-family: Arial;">encoder</span>。</span><span style="font-family: Arial;"><span> </span></span></span></p>
<p><strong><span style="font-family: Arial;"><span style="font-size: small;">CharsetDecoder</span></span></strong></p>
<p style="padding-left: 30px;"><span style="font-size: small;"><span>将按某种字符集编码的字节流解码为<span style="font-family: Arial;">unicode</span>字符数据的引擎。</span><span style="font-family: Arial;"><span> </span></span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small;"><span><span style="font-family: Arial;">CharsetDecoder</span>的输入是<span style="font-family: Arial;">ByteBuffer</span>，输出是<span style="font-family: Arial;">CharBuffer</span>。进行<span style="font-family: Arial;">decode</span>操作时一般按如下步骤进行：</span><span style="font-family: Arial;"><span> </span></span></span></p>
<p style="padding-left: 30px;"><span><span style="font-size: small;"><span style="font-family: Arial;">1．</span> 调用<span style="font-family: Arial;">CharsetDecoder</span>的<span style="font-family: Arial;">reset()</span>方法。（第一次使用时可不调用）</span></span></p>
<p style="padding-left: 30px;"><span><span style="font-size: small;"><span style="font-family: Arial;">2．</span> 调用<span style="font-family: Arial;">decode()</span>方法<span style="font-family: Arial;">0</span>到<span style="font-family: Arial;">n</span>次，将<span style="font-family: Arial;">endOfInput</span>参数设为<span style="font-family: Arial;">false</span>，告诉<span style="font-family: Arial;">decoder</span>有可能还有新的数据送入。</span></span></p>
<p style="padding-left: 30px;"><span><span style="font-size: small;"><span style="font-family: Arial;">3．</span> 调用<span style="font-family: Arial;">decode()</span>方法最后一次，将<span style="font-family: Arial;">endOfInput</span>参数设为<span style="font-family: Arial;">true</span>，告诉<span style="font-family: Arial;">decoder</span>所有数据都已经送入。</span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small;"><span><span style="font-family: Arial;">4．</span> 调用<span style="font-family: Arial;">decoder</span>的<span style="font-family: Arial;">flush()</span>方法。让<span style="font-family: Arial;">decoder</span>有机会把一些内部状态写到输出的<span style="font-family: Arial;">CharBuffer</span>中。</span><span style="font-family: Arial;"><span> </span></span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">CharsetDecoder reset()</span></p>
<p style="padding-left: 30px;"><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>重置<span style="font-family: Arial;">decoder</span>，并清除<span style="font-family: Arial;">decoder</span>中的一些内部状态。</span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">CoderResult decode(ByteBuffer in, CharBuffer out, boolean endOfInput)</span></p>
<p style="padding-left: 30px;"><span style="font-size: small;">从<span style="font-family: Arial;">ByteBuffer</span>类型的输入中<span style="font-family: Arial;">decode</span>尽可能多的字节，并将结果写到<span style="font-family: Arial;">CharBuffer</span>类型的输出中。根据<span style="font-family: Arial;">decode</span>的结果，可能返回<span style="font-family: Arial;">3</span>种<span style="font-family: Arial;">CoderResult</span>：<span style="font-family: Arial;">CoderResult.UNDERFLOW</span>表示已经没有输入可以<span style="font-family: Arial;">decode</span>；<span style="font-family: Arial;">CoderResult.OVERFLOW</span>表示输出已满；其它的<span style="font-family: Arial;">CoderResult</span>表示<span style="font-family: Arial;">decode</span>过程中有错误发生。根据返回的结果，应用程序可以采取相应的措施，比如，增加输入，清除输出等等，然后再次调用<span style="font-family: Arial;">decode()</span>方法。</span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">CoderResult flush(CharBuffer out)</span></p>
<p style="padding-left: 30px;"><span style="font-size: small;">有些<span style="font-family: Arial;">decoder</span>会在<span style="font-family: Arial;">decode</span>的过程中保留一些内部状态，调用这个方法让这些<span style="font-family: Arial;">decoder</span>有机会将这些内部状态写到输出的<span style="font-family: Arial;">CharBuffer</span>中。调用成功返回<span style="font-family: Arial;">CoderResult.UNDERFLOW</span>。如果输出的空间不够，该函数返回<span style="font-family: Arial;">CoderResult.OVERFLOW</span>，这时应用程序应该扩大输出<span style="font-family: Arial;">CharBuffer</span>的空间，然后再次调用该方法。</span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">CharBuffer decode(ByteBuffer in)</span></p>
<p style="padding-left: 30px;"><span style="font-size: small;"><span>一个便捷的方法把<span style="font-family: Arial;">ByteBuffer</span>中的内容<span style="font-family: Arial;">decode</span>到一个新创建的<span style="font-family: Arial;">CharBuffer</span>中。在这个方法中包括了前面提到的<span style="font-family: Arial;">4</span>个步骤，所以不能和前<span style="font-family: Arial;">3</span>个函数一起使用。</span><span style="font-family: Arial;"><span> </span></span></span></p>
<p style="padding-left: 30px;"><span><span style="font-size: small;"><span style="font-family: Arial;">decode</span>过程中的错误有两种：<span style="font-family: Arial;">malformed-input CoderResult</span>表示输入中数据有误；<span style="font-family: Arial;">unmappable-character CoderResult</span>表示输入中有数据无法被解码成<span style="font-family: Arial;">unicode</span>的字符。如何处理<span style="font-family: Arial;">decode</span>过程中的错误取决于<span style="font-family: Arial;">decoder</span>的设置。对于这两种错误，<span style="font-family: Arial;">decoder</span>可以通过<span style="font-family: Arial;">CodingErrorAction</span>设置成：</span></span></p>
<p style="padding-left: 30px;"><span><span style="font-size: small;"><span style="font-family: Arial;">1．</span> 忽略错误</span></span></p>
<p style="padding-left: 30px;"><span><span style="font-size: small;"><span style="font-family: Arial;">2．</span> 报告错误。（这会导致错误发生时，<span style="font-family: Arial;">decode()</span>方法返回一个表示该错误的<span style="font-family: Arial;">CoderResult</span>。）</span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small;"><span><span style="font-family: Arial;">3．</span> 替换错误，用<span style="font-family: Arial;">decoder</span>中的替换字串替换掉有错误的部分。</span><span style="font-family: Arial;"><span> </span></span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small;"><span style="font-family: Arial;">CodingErrorAction malformedInputAction()</span> </span></p>
<p style="padding-left: 30px;"><span style="font-size: small;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 返回<span style="font-family: Arial;">malformed-input</span>的出错处理。</span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">CharsetDecoder onMalformedInput(CodingErrorAction newAction)</span></p>
<p style="padding-left: 30px;"><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>设置<span style="font-family: Arial;">malformed-input</span>的出错处理。</span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">CodingErrorAction unmappableCharacterAction()</span></p>
<p style="padding-left: 30px;"><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>返回<span style="font-family: Arial;">unmappable-character</span>的出错处理。</span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">CharsetDecoder onUnmappableCharacter(CodingErrorAction newAction)</span></p>
<p style="padding-left: 30px;"><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>设置<span style="font-family: Arial;">unmappable-character</span>的出错处理。</span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">String replacement()</span></p>
<p style="padding-left: 30px;"><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>返回<span style="font-family: Arial;">decoder</span>的替换字串。</span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">CharsetDecoder replaceWith(String newReplacement)</span></p>
<p style="padding-left: 30px;"><span style="font-size: small;"><span><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>设置<span style="font-family: Arial;">decoder</span>的替换字串。</span><span style="font-family: Arial;"><span> </span></span></span></p>
<p><strong><span style="font-family: Arial;"><span style="font-size: small;">CharsetEncoder</span></span></strong></p>
<p><span style="font-size: small;"><span><strong><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></strong>将<span style="font-family: Arial;">unicode</span>字符数据编码为特定字符集的字节流的引擎。其接口和<span style="font-family: Arial;">CharsetDecoder</span>相类似。</span><span style="font-family: Arial;"><span> </span></span></span></p>
<p><strong><span style="font-family: Arial;"><span style="font-size: small;">CoderResult</span></span></strong></p>
<p style="padding-left: 30px;"><span style="font-size: small;"><span>描述<span style="font-family: Arial;">encode/decode</span>操作结果的类。</span><span style="font-family: Arial;"><span> </span></span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small;"><span><span style="font-family: Arial;">CodeResult</span>包含两个<span style="font-family: Arial;">static</span>成员：</span><span style="font-family: Arial;"><span> </span></span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">CoderResult OVERFLOW</span></p>
<p style="padding-left: 30px;"><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>表示输出已满</span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">CoderResult UNDERFLOW</span></p>
<p style="padding-left: 30px;"><span style="font-size: small;"><span><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>表示输入已无数据可用。</span><span style="font-family: Arial;"><span> </span></span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small;"><span>其主要的成员函数有：</span><span style="font-family: Arial;"><span> </span></span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">boolean isError()</span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">boolean isMalformed()</span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">boolean isUnmappable()</span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">boolean isOverflow()</span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">boolean isUnderflow()</span></p>
<p style="padding-left: 30px;"><span style="font-size: small;"><span><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;</span>用于判断该<span style="font-family: Arial;">CoderResult</span>描述的错误。</span><span style="font-family: Arial;"><span> </span></span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">int length()</span></p>
<p style="padding-left: 30px;"><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>返回错误的长度，比如，无法被转换成<span style="font-family: Arial;">unicode</span>的字节长度。</span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">void throwException()</span></p>
<p style="padding-left: 30px;"><span style="font-size: small;"><span><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>抛出一个和这个<span style="font-family: Arial;">CoderResult</span>相对应的<span style="font-family: Arial;">exception</span>。</span><span style="font-family: Arial;"><span> </span></span></span></p>
<p><strong><span style="font-family: Arial;"><span style="font-size: small;">CodingErrorAction</span></span></strong></p>
<p style="padding-left: 30px;"><span style="font-size: small;"><span>表示<span style="font-family: Arial;">encoder/decoder</span>中错误处理方法的类。可将其看成一个<span style="font-family: Arial;">enum</span>类型。有以下<span style="font-family: Arial;">static</span>属性：</span><span style="font-family: Arial;"><span> </span></span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">CodingErrorAction IGNORE</span></p>
<p style="padding-left: 30px;"><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>忽略错误。</span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">CodingErrorAction REPLACE</span></p>
<p style="padding-left: 30px;"><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>用替换字串替换有错误的部分。</span></span></p>
<p style="padding-left: 30px;"><span style="font-size: small; font-family: Arial;">CodingErrorAction REPORT</span></p>
<p style="padding-left: 30px;"><span style="font-size: small;">报告错误，对于不同的函数，有可能是返回一个和错误有关的<span style="font-family: Arial;">CoderResult</span>，也有可能是抛出一个<span style="font-family: Arial;">CharacterCodingException</span>。</span></p>
</div>
          <br/><br/>
          <span style="color:red;">
            <a href="http://wufan0023.javaeye.com/blog/198722#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 30 May 2008 16:25:03 +0800</pubDate>
        <link>http://wufan0023.javaeye.com/blog/198722</link>
        <guid>http://wufan0023.javaeye.com/blog/198722</guid>
      </item>
          <item>
        <title>Java NIO API详解 (I)[z]</title>
        <author>wufan0023</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://wufan0023.javaeye.com">wufan0023</a>&nbsp;
                    链接：<a href="http://wufan0023.javaeye.com/blog/198710" style="color:red;">http://wufan0023.javaeye.com/blog/198710</a>&nbsp;
          发表时间: 2008年05月30日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><span><span style="font-size: small;"><span style="font-family: Arial;">NIO API</span>主要集中在<span style="font-family: Arial;">java.nio</span>和它的<span style="font-family: Arial;">subpackages</span>中：</span></span></p>
<p><span style="font-size: small; font-family: Arial;"><strong>java.nio</strong></span></p>
<p><span style="font-size: small;">定义了<span style="font-family: Arial;">Buffer</span>及其数据类型相关的子类。其中被<span style="font-family: Arial;">java.nio.channels</span>中的类用来进行<span style="font-family: Arial;">IO</span>操作的<span style="font-family: Arial;">ByteBuffer</span>的作用非常重要。</span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><span style="font-size: small; color: #000000; font-family: Arial;"><strong>java.nio.channels</strong></span></p>
<p><span style="font-size: small;">定义了一系列处理<span style="font-family: Arial;">IO</span>的<span style="font-family: Arial;">Channel</span>接口以及这些接口在文件系统和网络通讯上的实现。通过<span style="font-family: Arial;">Selector</span>这个类，还提供了进行异步<span style="font-family: Arial;">IO</span>操作的办法。这个包可以说是<span style="font-family: Arial;">NIO API</span>的核心。</span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><span style="font-size: small; font-family: Arial;"><strong>java.nio.channels.spi</strong></span></p>
<p><span style="font-size: small;">定义了可用来实现<span style="font-family: Arial;">channel</span>和<span style="font-family: Arial;">selector API</span>的抽象类。</span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><span style="font-size: small; font-family: Arial;"><strong>java.nio.charset</strong></span></p>
<p><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>定义了处理字符编码和解码的类。</span></span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><span style="font-size: small; font-family: Arial;"><strong>java.nio.charset.spi</strong></span></p>
<p><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>定义了可用来实现<span style="font-family: Arial;">charset API</span>的抽象类。</span></span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><span><span style="font-size: small;"><span style="font-family: Arial;">java.nio.channels.spi</span>和<span style="font-family: Arial;">java.nio.charset.spi</span>这两个包主要被用来对现有<span style="font-family: Arial;">NIO API</span>进行扩展，在实际的使用中，我们一般只和另外的<span style="font-family: Arial;">3</span>个包打交道。下面将对这<span style="font-family: Arial;">3</span>个包一一介绍。</span></span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><span style="font-family: Arial;"><span style="font-size: small;">Package java.nio</span></span></p>
<p><span style="font-size: small;">这个包主要定义了<span style="font-family: Arial;">Buffer</span>及其子类。<span style="font-family: Arial;">Buffer</span>定义了一个线性存放<span style="font-family: Arial;">primitive type</span>数据的容器接口。对于除<span style="font-family: Arial;">boolean</span>以外的其他<span style="font-family: Arial;">primitive type</span>，都有一个相应的<span style="font-family: Arial;">Buffer</span>子类，<span style="font-family: Arial;">ByteBuffer</span>是其中最重要的一个子类。</span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><span style="font-size: small;">下面这张<span style="font-family: Arial;">UML</span>类图描述了<span style="font-family: Arial;">java.nio</span>中的类的关系：</span></p>
<p align="center"><span style="font-size: small;">&nbsp;</span></p>
<p><span style="font-family: Arial;"><span><br /></span></span></p>
<div><span style="font-size: small;"><img class="blogimg" src="http://hiphotos.baidu.com/yaolihui/pic/item/de5163602621adcc8db10d99.jpg" border="0" alt="" /></span></div>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><strong><span style="font-family: Arial;"><span style="font-size: small;">Buffer</span></span></strong></p>
<p><span style="font-size: small;">定义了一个可以线性存放<span style="font-family: Arial;">primitive type</span>数据的容器接口。<span style="font-family: Arial;">Buffer</span>主要包含了与类型（<span style="font-family: Arial;">byte, char&hellip;</span>）无关的功能。值得注意的是<span style="font-family: Arial;">Buffer</span>及其子类都不是线程安全的。</span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><span style="font-size: small;">每个<span style="font-family: Arial;">Buffer</span>都有以下的属性：</span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><span style="font-size: small; font-family: Arial; background-color: #ffffff;"><em>capacity</em></span></p>
<p><span style="font-size: small;">这个<span style="font-family: Arial;">Buffer</span>最多能放多少数据。<span style="font-family: Arial;">capacity</span>一般在<span style="font-family: Arial;">buffer</span>被创建的时候指定。</span></p>
<p><span style="font-size: small; font-family: Arial; background-color: #ffffff;"><em>limit</em></span></p>
<p><span style="font-size: small;">在<span style="font-family: Arial;">Buffer</span>上进行的读写操作都不能越过这个下标。当写数据到<span style="font-family: Arial;">buffer</span>中时，<span style="font-family: Arial;">limit</span>一般和<span style="font-family: Arial;">capacity</span>相等，当读数据时，<span style="font-family: Arial;">limit</span>代表<span style="font-family: Arial;">buffer</span>中有效数据的长度。</span></p>
<p><span style="font-size: small; font-family: Arial; background-color: #ffffff;"><em>position</em></span></p>
<p><span style="font-size: small;">读<span style="font-family: Arial;">/</span>写操作的当前下标。当使用<span style="font-family: Arial;">buffer</span>的相对位置进行读<span style="font-family: Arial;">/</span>写操作时，读<span style="font-family: Arial;">/</span>写会从这个下标进行，并在操作完成后，<span style="font-family: Arial;">buffer</span>会更新下标的值。</span></p>
<p><span style="font-size: small; font-family: Arial; background-color: #ffffff;"><em>mark</em></span></p>
<p><span style="font-size: small;">一个临时存放的位置下标。调用<span style="font-family: Arial;">mark()</span>会将<span style="font-family: Arial;">mark</span>设为当前的<span style="font-family: Arial;">position</span>的值，以后调用<span style="font-family: Arial;">reset()</span>会将<span style="font-family: Arial;">position</span>属性设置为<span style="font-family: Arial;">mark</span>的值。<span style="font-family: Arial;">mark</span>的值总是小于等于<span style="font-family: Arial;">position</span>的值，如果将<span style="font-family: Arial;">position</span>的值设的比<span style="font-family: Arial;">mark</span>小，当前的<span style="font-family: Arial;">mark</span>值会被抛弃掉。</span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><span style="font-size: small;">这些属性总是<strong>满足以下条件</strong>：</span></p>
<p><span style="font-family: Arial;"><span style="font-size: small; color: #3366ff;">0 &lt;= mark &lt;= position &lt;= limit &lt;= capacity</span></span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><span><span style="font-size: small;"><span style="font-family: Arial;">limit</span>和<span style="font-family: Arial;">position</span>的值除了通过<span style="font-family: Arial;">limit()</span>和<span style="font-family: Arial;">position()</span>函数来设置，也可以通过下面这些函数来改变：</span></span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><span style="font-family: Arial;"><span style="font-size: small;">Buffer <span style="color: #3366ff;">clear()</span></span></span></p>
<p><span style="font-size: small;">把<span style="font-family: Arial;">position</span>设为<span style="font-family: Arial;">0</span>，把<span style="font-family: Arial;">limit</span>设为<span style="font-family: Arial;">capacity</span>，一般在把数据写入<span style="font-family: Arial;">Buffer</span>前调用。</span></p>
<p><span style="font-family: Arial;"><span style="font-size: small;">Buffer <span style="color: #3366ff;">flip()</span></span></span></p>
<p><span style="font-size: small;">把<span style="font-family: Arial;">limit</span>设为当前<span style="font-family: Arial;">position</span>，把<span style="font-family: Arial;">position</span>设为<span style="font-family: Arial;">0</span>，一般在从<span style="font-family: Arial;">Buffer</span>读出数据前调用。</span></p>
<p><span style="font-family: Arial;"><span style="font-size: small;">Buffer <span style="color: #3366ff;">rewind()</span></span></span></p>
<p><span style="font-size: small;">把<span style="font-family: Arial;">position</span>设为<span style="font-family: Arial;">0</span>，<span style="font-family: Arial;">limit</span>不变，一般在把数据重写入<span style="font-family: Arial;">Buffer</span>前调用。</span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><span><span style="font-size: small;"><span style="font-family: Arial;">Buffer</span>对象有可能是只读的，这时，任何对该对象的写操作都会触发一个<span style="font-family: Arial;">ReadOnlyBufferException</span>。<span style="font-family: Arial;">isReadOnly()</span>方法可以用来判断一个<span style="font-family: Arial;">Buffer</span>是否只读。</span></span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><strong><span style="font-family: Arial;"><span style="font-size: small;">ByteBuffer</span></span></strong></p>
<p><span><span style="font-size: small;">在<span style="font-family: Arial;">Buffer<span>的子类中，<span style="font-family: Arial;">ByteBuffer</span>是一个地位较为特殊的类，因为在<span style="font-family: Arial;">java.io.channels</span>中定义的各种<span style="font-family: Arial;">channel</span>的<span style="font-family: Arial;">IO</span>操作基本上都是围绕<span style="font-family: Arial;">ByteBuffer</span>展开的。</span> </span></span></span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><span><span style="font-size: small;"><span style="font-family: Arial;">ByteBuffer</span>定义了<span style="font-family: Arial;">4</span>个<span style="font-family: Arial;">static</span>方法来做<strong>创建工作</strong>：</span></span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><span style="font-size: small; font-family: Arial;"><strong>ByteBuffer allocate(int capacity)</strong></span></p>
<p><span style="font-size: small;">创建一个指定<span style="font-family: Arial;">capacity</span>的<span style="font-family: Arial;">ByteBuffer</span>。</span></p>
<p><span style="font-size: small; font-family: Arial;"><strong>ByteBuffer allocateDirect(int capacity)</strong></span></p>
<p><span style="font-size: small;">创建一个<span style="font-family: Arial;">direct</span>的<span style="font-family: Arial;">ByteBuffer</span>，这样的<span style="font-family: Arial;">ByteBuffer</span>在参与<span style="font-family: Arial;">IO</span>操作时性能会更好（很有可能是在底层的实现使用了<span style="font-family: Arial;">DMA</span>技术），相应的，创建和回收<span style="font-family: Arial;">direct</span>的<span style="font-family: Arial;">ByteBuffer</span>的代价也会高一些。<span style="font-family: Arial;">isDirect()</span>方法可以检查一个<span style="font-family: Arial;">buffer</span>是否是<span style="font-family: Arial;">direct</span>的。</span></p>
<p><span style="font-size: small; font-family: Arial;"><strong>ByteBuffer wrap(byte [] array)</strong></span></p>
<p><span style="font-size: small; font-family: Arial;"><strong>ByteBuffer wrap(byte [] array, int offset, int length)</strong></span></p>
<p><span style="font-size: small;">把一个<span style="font-family: Arial;">byte</span>数组或<span style="font-family: Arial;">byte</span>数组的一部分包装成<span style="font-family: Arial;">ByteBuffer</span>。</span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><span><span style="font-size: small;"><span style="font-family: Arial;">ByteBuffer</span>定义了一系列<span style="font-family: Arial;">get</span>和<span style="font-family: Arial;">put</span>操作来从中读写<span style="font-family: Arial;">byte</span>数据，如下面几个：</span></span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><span style="font-family: Arial;"><span style="font-size: small;">byte <span style="color: #3366ff;">get()</span></span></span></p>
<p><span style="font-family: Arial;"><span style="font-size: small;">ByteBuffer <span style="color: #3366ff;">get(byte [] dst)</span></span></span></p>
<p><span style="font-family: Arial;"><span style="font-size: small;">byte <span style="color: #3366ff;">get(int index)</span></span></span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><span style="font-family: Arial;"><span style="font-size: small;">ByteBuffer <span style="color: #3366ff;">put(byte b)</span></span></span></p>
<p><span style="font-family: Arial;"><span style="font-size: small;">ByteBuffer<span style="color: #3366ff;"> put(byte [] src)</span></span></span></p>
<p><span style="font-family: Arial;"><span style="font-size: small;">ByteBuffer <span style="color: #3366ff;">put(int index, byte b)</span></span></span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><span style="font-size: small;">这些操作可分为绝对定位和相对定为两种，相对定位的读写操作依靠<span style="font-family: Arial;">position</span>来定位<span style="font-family: Arial;">Buffer</span>中的位置，并在操作完成后会更新<span style="font-family: Arial;">position</span>的值。</span></p>
<p><span style="font-size: small;">在其它类型的<span style="font-family: Arial;">buffer</span>中，也定义了相同的函数来读写数据，唯一不同的就是一些参数和返回值的类型。</span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><span style="font-size: small;">除了读写<span style="font-family: Arial;">byte</span>类型数据的函数，<span style="font-family: Arial;">ByteBuffer</span>的一个特别之处是它还定义了读写其它<span style="font-family: Arial;">primitive</span>数据的方法，如：</span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><span style="font-family: Arial;"><span style="font-size: small;">int <span style="color: #3366ff;">getInt()</span></span></span></p>
<p><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>从<span style="font-family: Arial;">ByteBuffer</span>中读出一个<span style="font-family: Arial;">int</span>值。</span></span></p>
<p><span style="font-family: Arial;"><span style="font-size: small;">ByteBuffer <span style="color: #3366ff;">putInt(int value)</span></span></span></p>
<p><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>写入一个<span style="font-family: Arial;">int</span>值到<span style="font-family: Arial;">ByteBuffer</span>中。</span></span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><span style="font-size: small;">读写其它类型的数据牵涉到字节序问题，<span style="font-family: Arial;">ByteBuffer</span>会按其字节序（大字节序或小字节序）写入或读出一个其它类型的数据（<span style="font-family: Arial;">int,long&hellip;</span>）。字节序可以用<span style="font-family: Arial;">order</span>方法来取得和设置：</span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><span style="font-family: Arial;"><span style="font-size: small;">ByteOrder <span style="color: #3366ff;">order()</span></span></span></p>
<p><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>返回<span style="font-family: Arial;">ByteBuffer</span>的字节序。</span></span></p>
<p><span style="font-family: Arial;"><span style="font-size: small;">ByteBuffer <span style="color: #3366ff;">order(ByteOrder bo)</span></span></span></p>
<p><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>设置<span style="font-family: Arial;">ByteBuffer</span>的字节序。</span></span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><span><span style="font-size: small;"><span style="font-family: Arial;">ByteBuffer</span>另一个特别的地方是可以在它的基础上得到其它类型的<span style="font-family: Arial;">buffer</span>。如：</span></span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><span style="font-family: Arial;"><span style="font-size: small;">CharBuffer <span style="color: #3366ff;">asCharBuffer()</span></span></span></p>
<p><span style="font-size: small;">为当前的<span style="font-family: Arial;">ByteBuffer</span>创建一个<span style="font-family: Arial;">CharBuffer</span>的视图。在该视图<span style="font-family: Arial;">buffer</span>中的读写操作会按照<span style="font-family: Arial;">ByteBuffer</span>的字节序作用到<span style="font-family: Arial;">ByteBuffer</span>中的数据上。</span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><span style="font-size: small;">用这类方法创建出来的<span style="font-family: Arial;">buffer</span>会从<span style="font-family: Arial;">ByteBuffer</span>的<span style="font-family: Arial;">position</span>位置开始到<span style="font-family: Arial;">limit</span>位置结束，可以看作是这段数据的视图。视图<span style="font-family: Arial;">buffer</span>的<span style="font-family: Arial;">readOnly</span>属性和<span style="font-family: Arial;">direct</span>属性与<span style="font-family: Arial;">ByteBuffer</span>的一致，而且也只有通过这种方法，才可以得到其他数据类型的<span style="font-family: Arial;">direct buffer</span>。</span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><strong><span style="font-family: Arial;"><span style="font-size: small;">ByteOrder</span></span></strong></p>
<p><span style="font-size: small;">用来表示<span style="font-family: Arial;">ByteBuffer</span>字节序的类，可将其看成<span style="font-family: Arial;">java</span>中的<span style="font-family: Arial;">enum</span>类型。主要定义了下面几个<span style="font-family: Arial;">static</span>方法和属性：</span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><span style="font-family: Arial;"><span style="font-size: small;">ByteOrder <span style="color: #3366ff;">BIG_ENDIAN</span></span></span></p>
<p><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>代表大字节序的<span style="font-family: Arial;">ByteOrder</span>。</span></span></p>
<p><span style="font-family: Arial;"><span style="font-size: small;">ByteOrder <span style="color: #3366ff;">LITTLE_ENDIAN</span></span></span></p>
<p><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>代表小字节序的<span style="font-family: Arial;">ByteOrder</span>。</span></span></p>
<p><span style="font-family: Arial;"><span style="font-size: small;">ByteOrder <span style="color: #3366ff;">nativeOrder()</span></span></span></p>
<p><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>返回当前硬件平台的字节序。</span></span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><strong><span style="font-family: Arial;"><span style="font-size: small;">MappedByteBuffer</span></span></strong></p>
<p><span><span style="font-size: small;"><span style="font-family: Arial;">ByteBuffer</span>的子类，是文件内容在内存中的映射。这个类的实例需要通过<span style="font-family: Arial;">FileChannel</span>的<span style="font-family: Arial;">map()</span>方法来创建。</span></span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><span style="font-size: small;">接下来看看一个使用<span style="font-family: Arial;">ByteBuffer</span>的例子，这个例子从标准输入不停地读入字符，当读满一行后，将收集的字符写到标准输出：</span></p>
<p>
<table cellspacing="0" border="1" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="568">
<p align="left">&nbsp;&nbsp;&nbsp; <strong>public</strong> <strong>static</strong> <strong>void</strong> main(String [] args) <strong>throws</strong> IOException {</p>
<p align="left">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 创建一个capacity为256的ByteBuffer</p>
<p align="left">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ByteBuffer buf = ByteBuffer.allocate(256);</p>
<p align="left">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>while</strong> (<strong>true</strong>) {</p>
<p align="left">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 从标准输入流读入一个字符</p>
<p align="left">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>int</strong> c = System.in.read();</p>
<p align="left">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 当读到输入流结束时，退出循环</p>
<p align="left">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>if</strong> (c == -1)</p>
<p align="left">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>break</strong>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p align="left">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 把读入的字符写入ByteBuffer中</p>
<p align="left">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buf.put((<strong>byte</strong>) c);</p>
<p align="left">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 当读完一行时，输出收集的字符</p>
<p align="left">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>if</strong> (c == '\n') {</p>
<p align="left">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 调用flip()使limit变为当前的position的值,position变为0,</p>
<p align="left">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 为接下来从ByteBuffer读取做准备</p>
<p align="left">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buf.flip();</p>
<p align="left">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 构建一个byte数组</p>
<p align="left">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>byte</strong> [] content = <strong>new</strong> <strong>byte</strong>[buf.limit()];</p>
<p align="left">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 从ByteBuffer中读取数据到byte数组中</p>
<p align="left">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buf.get(content);</p>
<p align="left">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 把byte数组的内容写到标准输出</p>
<p align="left">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.print(<strong>new</strong> String(content));</p>
<p align="left">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 调用clear()使position变为0,limit变为capacity的值，</p>
<p align="left">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 为接下来写入数据到ByteBuffer中做准备</p>
<p align="left">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buf.clear();</p>
<p align="left">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p align="left">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</p>
<p>&nbsp;&nbsp;&nbsp; }</p>
</td>
</tr>
</tbody>
</table>
</p>
<p><span style="font-size: x-small;"><span style="font-family: Arial;">
<p><span style="font-family: Arial;"><span style="font-size: small;">Package java.nio.channels</span></span></p>
<p><span style="font-size: small;">这个包定义了<span style="font-family: Arial;">Channel</span>的概念，<span style="font-family: Arial;"><strong>Channel</strong></span><span style="text-decoration: underline;">表现了一个可以进行<span style="font-family: Arial;">IO</span>操作的通道</span>（比如，通过<span style="font-family: Arial;">FileChannel</span>，我们可以对文件进行读写操作）。<span style="font-family: Arial;">java.nio.channels</span>包含了文件系统和网络通讯相关的<span style="font-family: Arial;">channel</span>类。这个包通过<span style="font-family: Arial;">Selector</span>和<span style="font-family: Arial;">SelectableChannel</span>这两个类，还定义了一个进行异步（<span style="font-family: Arial;">non-blocking</span>）<span style="font-family: Arial;">IO</span>操作的<span style="font-family: Arial;">API</span>，这对需要高性能<span style="font-family: Arial;">IO</span>的应用非常重要。</span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><span style="font-size: small;">下面这张<span style="font-family: Arial;">UML</span>类图描述了<span style="font-family: Arial;">java.nio.channels</span>中<span style="font-family: Arial;">interface</span>的关系：</span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<div><span style="font-size: small;"><img class="blogimg" src="http://hiphotos.baidu.com/yaolihui/pic/item/c58ff11b999f0ee9af513399.jpg" border="0" alt="" /></span></div>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><strong><span style="font-size: small; font-family: Arial;">Channel</span></strong></p>
<p style="PADDING-LEFT: 30px"><span><span style="font-size: small;"><span style="font-family: Arial;">Channel</span>表现了一个可以进行<span style="font-family: Arial;">IO</span>操作的通道，该<span style="font-family: Arial;">interface</span>定义了以下方法：</span></span></p>
<p style="PADDING-LEFT: 30px"><span style="font-size: small;">&nbsp;</span></p>
<p style="PADDING-LEFT: 30px"><span style="font-size: small; font-family: Arial;">boolean isOpen()</span></p>
<p style="PADDING-LEFT: 30px"><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>该<span style="font-family: Arial;">Channel</span>是否是打开的。</span></span></p>
<p style="PADDING-LEFT: 30px"><span style="font-size: small; font-family: Arial;">void close()</span></p>
<p style="PADDING-LEFT: 30px"><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>关闭这个<span style="font-family: Arial;">Channel</span>，相关的资源会被释放。</span></span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><strong><span style="font-family: Arial;"><span style="font-size: small;">ReadableByteChannel</span></span></strong></p>
<p style="PADDING-LEFT: 30px"><span style="font-size: small;">定义了一个可从中读取<span style="font-family: Arial;">byte</span>数据的<span style="font-family: Arial;">channel interface</span>。</span></p>
<p style="PADDING-LEFT: 30px"><span style="font-size: small;">&nbsp;</span></p>
<p style="PADDING-LEFT: 30px"><span style="font-size: small; font-family: Arial;">int read(ByteBuffer dst)</span></p>
<p style="PADDING-LEFT: 30px"><span style="font-size: small;">从<span style="font-family: Arial;">channel</span>中读取<span style="font-family: Arial;">byte</span>数据并写到<span style="font-family: Arial;">ByteBuffer</span>中。返回读取的<span style="font-family: Arial;">byte</span>数。</span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><strong><span style="font-family: Arial;"><span style="font-size: small;">WritableByteChannel</span></span></strong></p>
<p style="PADDING-LEFT: 30px"><span style="font-size: small;">定义了一个可向其写<span style="font-family: Arial;">byte</span>数据的<span style="font-family: Arial;">channel interface</span>。</span></p>
<p style="PADDING-LEFT: 30px"><span style="font-size: small;">&nbsp;</span></p>
<p style="PADDING-LEFT: 30px"><span style="font-size: small; font-family: Arial;">int write(ByteBuffer src)</span></p>
<p style="PADDING-LEFT: 30px"><span><span style="font-size: small;"><span style="font-family: Arial;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>从<span style="font-family: Arial;">ByteBuffer</span>中读取<span style="font-family: Arial;">byte</span>数据并写到<span style="font-family: Arial;">channel</span>中。返回写出的<span style="font-family: Arial;">byte</span>数。</span></span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><strong><span style="font-family: Arial;"><span style="font-size: small;">ByteChannel</span></span></strong></p>
<p style="PADDING-LEFT: 30px"><span><span style="font-size: small;"><span style="font-family: Arial;">ByteChannel</span>并没有定义新的方法，它的作用只是把<span style="font-family: Arial;">ReadableByteChannel</span>和<span style="font-family: Arial;">WritableByteChannel</span>合并在一起。</span></span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><strong><span style="font-family: Arial;"><span style="font-size: small;">ScatteringByteChannel</span></span></strong></p>
<p style="PADDING-LEFT: 30px"><span style="font-size: small;">继承了<span style="font-family: Arial;">ReadableByteChannel</span>并提供了同时往几个<span style="font-family: Arial;">ByteBuffer</span>中写数据的能力。</span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><strong><span style="font-family: Arial;"><span style="font-size: small;">GatheringByteChannel</span></span></strong></p>
<p style="PADDING-LEFT: 30px"><span style="font-size: small;">继承了<span style="font-family: Arial;">WritableByteChannel</span>并提供了同时从几个<span style="font-family: Arial;">ByteBuffer</span>中读数据的能力。</span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><strong><span style="font-family: Arial;"><span style="font-size: small;">InterruptibleChannel</span></span></strong></p>
<p style="PADDING-LEFT: 30px"><span style="font-size: small;">用来表现一个可以被异步关闭的<span style="font-family: Arial;">Channel</span>。这表现在两方面：</span></p>
<p style="PADDING-LEFT: 30px"><span><span style="font-size: small;"><span style="font-family: Arial;">1．</span>&nbsp;&nbsp;&nbsp; 当一个<span style="font-family: Arial;">InterruptibleChannel</span>的<span style="font-family: Arial;">close()</span>方法被调用时，其它<span style="font-family: Arial;">block</span>在这个<span style="font-family: Arial;">InterruptibleChannel</span>的<span style="font-family: Arial;">IO</span>操作上的线程会接收到一个<span style="font-family: Arial;">AsynchronousCloseException</span>。</span></span></p>
<p style="PADDING-LEFT: 30px"><span><span style="font-size: small;"><span style="font-family: Arial;">2．</span>&nbsp;&nbsp;&nbsp; 当一个线程<span style="font-family: Arial;">block</span>在<span style="font-family: Arial;">InterruptibleChannel</span>的<span style="font-family: Arial;">IO</span>操作上时，另一个线程调用该线程的<span style="font-family: Arial;">interrupt()</span>方法会导致<span style="font-family: Arial;">channel</span>被关闭，该线程收到一个<span style="font-family: Arial;">ClosedByInterruptException</span>，同时线程的<span style="font-family: Arial;">interrupt</span>状态会被设置。</span></span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><span style="font-size: small;">接下来的这张<span style="font-family: Arial;">UML</span>类图描述了<span style="font-family: Arial;">java.nio.channels</span>中类的关系：</span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<div><span style="font-size: small;"><img class="blogimg" src="http://hiphotos.baidu.com/yaolihui/pic/item/829ea625acb8af7334a80f99.jpg" border="0" alt="" /></span></div>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><strong><span><span style="font-size: small;">异步<span style="font-family: Arial;">IO</span></span></span></strong></p>
<p><span style="font-size: small;">异步<span style="font-family: Arial;">IO</span>的支持可以算是<span style="font-family: Arial;">NIO API</span>中最重要的功能，异步<span style="font-family: Arial;">IO</span>允许应用程序同时监控多个<span style="font-family: Arial;">channel</span>以提高性能，这一功能是<span style="text-decoration: underline;">通过<span style="font-family: Arial;"><strong>Selector</strong></span>，<span style="font-family: Arial;"><strong>SelectableChannel</strong></span>和<span style="font-family: Arial;"><strong>SelectionKey</strong></span>这<span style="font-family: Arial;">3</span>个类来实现的</span>。</span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><span><span style="font-size: small;"><span style="font-family: Arial;"><strong>SelectableChannel</strong></span><span style="text-decoration: underline;">代表了可以支持异步<span style="font-family: Arial;">IO</span>操作的<span style="font-family: Arial;">channel</span>，可以将其注册在<span style="font-family: Arial;">Selector</span>上</span>，这种注册的关系由<span style="font-family: Arial;">SelectionKey</span>这个类来表现（见<span style="font-family: Arial;">UML</span>图）。<span style="font-family: Arial;">Selector</span>这个类通过<span style="font-family: Arial;">select()</span>函数，给应用程序提供了一个可以同时监控多个<span style="font-family: Arial;">IO channel</span>的方法：</span></span></p>
<p><span style="font-size: small;">&nbsp;</span></p>
<p><span style="font-size: small;"><span>应用程序通过调用<span style="font-family: Arial;">select()</span>函数，让<span style="font-family: Arial;">Selector</span>监控注册在其上的多个<span style="font-family: Arial;">SelectableChannel</span>，当有<span style="font-family: Arial;">channel</span>的<span style="font-family: Arial;">IO</span>操作可以进行时，<span style="font-family: Arial;">select()</span>方法就会返回以让应用程序检查<span style="font-family: Arial;">channel</span>的状态，并作相应的处理。</span>&nbsp;</span></p>
<p><span style="font-size: small;">下面是<span style="font-family: Arial;">JDK 1.4</span>中异步<span style="font-family: Arial;">IO</span>的一个例子，这段<span style="font-family: Arial;">code</span>使用了异步<span style="font-family: Arial;">IO</span>实现了一个<span style="font-family: Arial;">time server</span>：</span></p>
<pre name="code" class="java">   private static void acceptConnections(int port) throws Exception {

       // 打开一个Selector

       Selector acceptSelector = SelectorProvider.provider().openSelector();


       // 创建一个ServerSocketChannel，这是一个SelectableChannel的子类

       ServerSocketChannel ssc = ServerSocketChannel.open();

       // 将其设为non-blocking状态，这样才能进行异步IO操作

       ssc.configureBlocking(false);


       // 给ServerSocketChannel对应的socket绑定IP和端口

       InetAddress lh = InetAddress.getLocalHost();

       InetSocketAddress isa = new InetSocketAddress(lh, port);

       ssc.socket().bind(isa);


       // 将ServerSocketChannel注册到Selector上，返回对应的SelectionKey

       SelectionKey acceptKey = ssc.register(acceptSelector, SelectionKey.OP_ACCEPT);


       int keysAdded = 0;


       // 用select()函数来监控注册在Selector上的SelectableChannel

       // 返回值代表了有多少channel可以进行IO操作 (ready for IO)

       while ((keysAdded = acceptSelector.select()) &gt; 0) {

           // selectedKeys()返回一个SelectionKey的集合，

           // 其中每个SelectionKey代表了一个可以进行IO操作的channel。

           // 一个ServerSocketChannel可以进行IO操作意味着有新的TCP连接连入了

           Set readyKeys = acceptSelector.selectedKeys();

           Iterator i = readyKeys.iterator();


           while (i.hasNext()) {

              SelectionKey sk = (SelectionKey) i.next();

              // 需要将处理过的key从selectedKeys这个集合中删除

              i.remove();

              // 从SelectionKey得到对应的channel

              ServerSocketChannel nextReady = (ServerSocketChannel) sk.channel();

              // 接受新的TCP连接

              Socket s = nextReady.accept().socket();

              // 把当前的时间写到这个新的TCP连接中

              PrintWriter out = new PrintWriter(s.getOutputStream(), true);

              Date now = new Date();

              out.println(now);

              // 关闭连接

              out.close();

           }

       }

    }
</pre>
<font size="2"><font face="Arial">
<p>&nbsp;</p>
</font></font></span><font size="2">
<p>&nbsp;</p>
</font></span></p>
<p><span style="font-size: small;">这是个纯粹用于演示的例子，因为只有一个<span style="font-family: Arial;">ServerSocketChannel</span>需要监控，所以其实并不真的需要使用到异步<span style="font-family: Arial;">IO</span>。不过正因为它的简单，可以很容易地看清楚异步<span style="font-family: Arial;">IO</span>是如何工作的。</span></p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://wufan0023.javaeye.com/blog/198710#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 30 May 2008 16:09:50 +0800</pubDate>
        <link>http://wufan0023.javaeye.com/blog/198710</link>
        <guid>http://wufan0023.javaeye.com/blog/198710</guid>
      </item>
          <item>
        <title>阻塞式线程池客户端</title>
        <author>wufan0023</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://wufan0023.javaeye.com">wufan0023</a>&nbsp;
                    链接：<a href="http://wufan0023.javaeye.com/blog/198655" style="color:red;">http://wufan0023.javaeye.com/blog/198655</a>&nbsp;
          发表时间: 2008年05月30日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <pre name="code" class="java">import java.net.*;
import java.nio.channels.*;
import java.nio.*;
import java.io.*;
import java.nio.charset.*;

public class EchoClient {
	private SocketChannel socketChannel = null;

	public EchoClient() throws IOException {
		socketChannel = SocketChannel.open(); // 打开通道
		// 设置连接地址和端口
		InetAddress ia = InetAddress.getLocalHost();
		InetSocketAddress isa = new InetSocketAddress(ia, 8001);
		try {
			socketChannel.connect(isa);// 连接远端
			System.out.println("与服务器的连接建立成功");
		} catch (ConnectException ce) {
			System.out.println("服务器无应答！");
		}
	}

	public void talk() throws IOException {
		try {
			BufferedReader br = getReader(socketChannel.socket());
			PrintWriter pw = getWriter(socketChannel.socket());
			BufferedReader localReader = new BufferedReader(
					new InputStreamReader(System.in));
			String msg = null;
			while ((msg = localReader.readLine()) != null) {
				pw.println(msg);
				System.out.println(br.readLine());

				if (msg.equals("bye"))
					break;
			}
		} catch (IOException e) {

		} finally {
			try {
				socketChannel.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	private PrintWriter getWriter(Socket socket) throws IOException {
		OutputStream socketOut = socket.getOutputStream();
		return new PrintWriter(socketOut, true);
	}

	private BufferedReader getReader(Socket socket) throws IOException {
		InputStream socketIn = socket.getInputStream();
		return new BufferedReader(new InputStreamReader(socketIn));
	}
	
	public static void main(String args[]) throws IOException {
		new EchoClient().talk();
	}
}</pre>
<p>&nbsp;</p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://wufan0023.javaeye.com/blog/198655#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 30 May 2008 13:42:14 +0800</pubDate>
        <link>http://wufan0023.javaeye.com/blog/198655</link>
        <guid>http://wufan0023.javaeye.com/blog/198655</guid>
      </item>
          <item>
        <title>阻塞式线程池服务器程序实例</title>
        <author>wufan0023</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://wufan0023.javaeye.com">wufan0023</a>&nbsp;
                    链接：<a href="http://wufan0023.javaeye.com/blog/198596" style="color:red;">http://wufan0023.javaeye.com/blog/198596</a>&nbsp;
          发表时间: 2008年05月30日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>Excutor&nbsp;接口&nbsp;---&nbsp;线程池<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #3366ff;">.execute(Runnable task) --- 执行Runnable类型的任务。</span></p>
<p><span style="color: #000000;">Executors&nbsp; ---&nbsp;负责生成各种连接池的实例<br /></span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.newCachedThreadPool()&nbsp; --- 有任务时才创建新线程，空闲线程保留60s。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.newFixedThreadPool(int nThreads)&nbsp; --- 创建固定数量的线程，空闲线程会一直保留。&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.newScheduledThreadPool(int corePoolSize) --- 线程池按照时间计划执行任务，允许设置任务执行时&nbsp; 间。参数为最小线程数。繁忙时，可能创建更多线程。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.newSingleThreadExecutor() ---&nbsp;只建立一个工作线程，依次执行每个任务。<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.newSingleThreadScheduledExecutor()&nbsp;----只一个线程，按时间计划执行任务。&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<p>ExecutorService --- 负责连接池的管理&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<pre name="code" class="java">import java.io.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.charset.*;
import java.net.*;
import java.util.*;
import java.util.concurrent.*;

public class EchoServer {
  private int port=8001;
  private ServerSocketChannel serverSocketChannel = null;
  private ExecutorService executorService;   //线程池
  private static final int POOL_MULTIPLE = 4;   //线程池数目
  
  /**
   * 负责构造线程池，启动服务区，并绑定端口
   * @throws IOException
   */
  public EchoServer() throws IOException {
	//创建线程池
    executorService= Executors.newFixedThreadPool(
	    Runtime.getRuntime().availableProcessors() * POOL_MULTIPLE);
    //创建通道
    serverSocketChannel= ServerSocketChannel.open();
    //在同一主机上关闭服务器程序，再启动该服务器服务时，能绑定同一端口。
    serverSocketChannel.socket().setReuseAddress(true);
    //绑定本地端口
    serverSocketChannel.socket().bind(new InetSocketAddress(port));
    System.out.println("服务器启动");
  }
  /**
   * 负责客户端连接，每接受一个客户连接，就把它交给线程池来处理。
   * 1.从线程池中取出空闲线程
   * 2.执行Handler的run()方法。
   */
  public void service() {
    while (true) {
      SocketChannel socketChannel=null;
      try {
        socketChannel = serverSocketChannel.accept();// 从连接池中获取一个连接通道
        executorService.execute(new Handler(socketChannel)); // 在工作线程中进行服务
      }catch (IOException e) {
         e.printStackTrace();
      }
    }
  }

  public static void main(String args[])throws IOException {
    new EchoServer().service();
  }
}
/**
 * 负责客户通信
 * @author Jethro Yan
 *
 */
class Handler implements Runnable{
  private SocketChannel socketChannel;
  public Handler(SocketChannel socketChannel){
    this.socketChannel=socketChannel;
  }
  public void run(){
    handle(socketChannel);
  }
  
  //负责和客户端通信工作。
  public void handle(SocketChannel socketChannel){
    try {
        Socket socket=socketChannel.socket();// 获得socket。
        System.out.println("接收到客户连接，来自: " +
        socket.getInetAddress() + ":" +socket.getPort());

        BufferedReader br =getReader(socket);
        PrintWriter pw = getWriter(socket);

        String msg = null;
        while ((msg = br.readLine()) != null) {
          System.out.println(msg);
          pw.println(echo(msg));
          if (msg.equals("bye"))
            break;
        }
      }catch (IOException e) {
         e.printStackTrace();
      }finally {
         try{
           if(socketChannel!=null)socketChannel.close();
         }catch (IOException e) {e.printStackTrace();}
      }
  }

  private PrintWriter getWriter(Socket socket)throws IOException{
    OutputStream socketOut = socket.getOutputStream();
    return new PrintWriter(socketOut,true);
  }
  private BufferedReader getReader(Socket socket)throws IOException{
    InputStream socketIn = socket.getInputStream();
    return new BufferedReader(new InputStreamReader(socketIn));
  }

  public String echo(String msg) {
    return "echo:" + msg;
  }
}</pre>
<p>&nbsp;</p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://wufan0023.javaeye.com/blog/198596#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 30 May 2008 11:26:21 +0800</pubDate>
        <link>http://wufan0023.javaeye.com/blog/198596</link>
        <guid>http://wufan0023.javaeye.com/blog/198596</guid>
      </item>
          <item>
        <title>Executors</title>
        <author>wufan0023</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://wufan0023.javaeye.com">wufan0023</a>&nbsp;
                    链接：<a href="http://wufan0023.javaeye.com/blog/198276" style="color:red;">http://wufan0023.javaeye.com/blog/198276</a>&nbsp;
          发表时间: 2008年05月29日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>
<table border="0" style="width: 569px; height: 113px; text-align: center;">
<tbody>
<tr>
<td style="text-align: left;">newCachedThreadPool</td>
<td style="text-align: left;">建立可以快取的Thread，每个Thread预设可idle 60秒 <br /></td>
</tr>
<tr>
<td style="text-align: left;">newFixedThreadPool </td>
<td style="text-align: left;">包括固定数量的Thread</td>
</tr>
<tr>
<td style="text-align: left;">newSingleThreadExecutor <br /></td>
<td style="text-align: left;">只有一个Thread，循序的执行指定给它的每个任务 <br /></td>
</tr>
<tr>
<td style="text-align: left;">&nbsp;newScheduledThreadPool</td>
<td style="TEXT-ALIGN: left">可排程的Thread <br /></td>
</tr>
<tr>
<td style="text-align: left;">&nbsp;newSingleThreadScheduledExecutor</td>
<td style="TEXT-ALIGN: left">单一可排程的Thread <br /></td>
</tr>
</tbody>
</table>
</p>
<pre name="code" class="java">package onlyfun.caterpillar;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ExecutorDemo {	
         public static void main(String[] args) {
                  ExecutorService service = Executors.newFixedThreadPool(5);
	        for(int i = 0; i &lt; 10; i++) {
 	            final int count = i;
	            service.submit(new Runnable() {
	               public void run() {
		    System.out.println(count);	
		     try {
		        Thread.sleep(2000);
		     } catch (InterruptedException e) {
		         e.printStackTrace();
		     }
	                }
	            });		
                      }				
                   service.shutdown(); // 最后记得关闭Thread pool	
            }
}</pre>
<p>&nbsp;</p>
<p>&nbsp;</p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://wufan0023.javaeye.com/blog/198276#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 29 May 2008 15:04:13 +0800</pubDate>
        <link>http://wufan0023.javaeye.com/blog/198276</link>
        <guid>http://wufan0023.javaeye.com/blog/198276</guid>
      </item>
          <item>
        <title>System.getProperty 常用参数</title>
        <author>wufan0023</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://wufan0023.javaeye.com">wufan0023</a>&nbsp;
                    链接：<a href="http://wufan0023.javaeye.com/blog/197532" style="color:red;">http://wufan0023.javaeye.com/blog/197532</a>&nbsp;
          发表时间: 2008年05月27日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <strong>java.version</strong><br />&nbsp;&nbsp; Java Runtime Environment version<br /><strong>java.vendor</strong><br />&nbsp;&nbsp; Java Runtime Environment vendor <br /><strong>java.vendor.url</strong><br />&nbsp;&nbsp; Java vendor URL <br /><strong>java.home</strong> <br />&nbsp;&nbsp; Java installation directory <br /><strong>java.vm.specification.version</strong> <br />&nbsp;&nbsp; Java Virtual Machine specification version <br /><strong>java.vm.specification.vendor </strong><br />&nbsp;&nbsp; Java Virtual Machine specification vendor <br /><strong>java.vm.specification.name</strong> <br />&nbsp;&nbsp; Java Virtual Machine specification name <br /><strong>java.vm.version</strong> <br />&nbsp;&nbsp; Java Virtual Machine implementation version <br /><strong>java.vm.vendor</strong> <br />&nbsp;&nbsp; Java Virtual Machine implementation vendor <br /><strong>java.vm.name</strong> <br />&nbsp;&nbsp; Java Virtual Machine implementation name <br /><strong>java.specification.version</strong> <br />&nbsp;&nbsp; Java Runtime Environment specification version<br /><strong>java.specification.vendor</strong><br />&nbsp;&nbsp; Java Runtime Environment specification vendor <br /><strong>java.specification.name </strong>&nbsp;&nbsp; <br />&nbsp;&nbsp; Java Runtime Environment specification name <br /><strong>java.class.version</strong> <br />&nbsp;&nbsp; Java class format version number <br /><strong>java.class.path</strong> <br />&nbsp;&nbsp; Java class path <br /><strong>java.library.path</strong><br />&nbsp;&nbsp; List of paths to search when loading libraries<br /><strong>java.io.tmpdir</strong><br />&nbsp;&nbsp; Default temp file path <br /><strong>java.compiler</strong><br />&nbsp;&nbsp; Name of JIT compiler to use <br /><strong>java.ext.dirs</strong> <br />&nbsp;&nbsp; Path of extension directory or directories<br /><strong>os.name</strong><br />&nbsp;&nbsp; Operating system name<br /><strong>os.arch</strong><br />&nbsp;&nbsp; Operating system architecture <br /><strong>os.version</strong><br />&nbsp;&nbsp; Operating system version <br /><strong>file.separator</strong><br />&nbsp;&nbsp; File separator ("/" on UNIX) <br /><strong>path.separator </strong><br />&nbsp;&nbsp; Path separator (":" on UNIX) <br /><strong>line.separator</strong><br />&nbsp;&nbsp; Line separator ("\n" on UNIX) <br /><strong>user.name</strong><br />&nbsp;&nbsp; User's account name <br /><strong>user.home</strong><br />&nbsp;&nbsp; User's home directory <br /><strong>user.dir</strong> <br />&nbsp;&nbsp; User's current working directory
          <br/><br/>
          <span style="color:red;">
            <a href="http://wufan0023.javaeye.com/blog/197532#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 27 May 2008 17:28:17 +0800</pubDate>
        <link>http://wufan0023.javaeye.com/blog/197532</link>
        <guid>http://wufan0023.javaeye.com/blog/197532</guid>
      </item>
          <item>
        <title>toString方法</title>
        <author>wufan0023</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://wufan0023.javaeye.com">wufan0023</a>&nbsp;
                    链接：<a href="http://wufan0023.javaeye.com/blog/197509" style="color:red;">http://wufan0023.javaeye.com/blog/197509</a>&nbsp;
          发表时间: 2008年05月27日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          很简单的代码，但是没有规范就写的很乱。<br />另外很多记录log的时候应该可以采用toString这样的方法来减少冗余。<br /><pre name="code" class="java">
  /**
     * &lt;p>Returns a String in the format: key[value1, value2, etc].&lt;/p>
     *
     * @return String representation of this message
     * @see java.lang.Object#toString()
     */
    public String toString() {
        StringBuffer buff = new StringBuffer();

        buff.append(this.key);
        buff.append("[");

        if (this.values != null) {
            for (int i = 0; i &lt; this.values.length; i++) {
                buff.append(this.values[i]);

                // don't append comma to last entry
                if (i &lt; (this.values.length - 1)) {
                    buff.append(", ");
                }
            }
        }

        buff.append("]");

        return buff.toString();
    }
</pre>
          <br/><br/>
          <span style="color:red;">
            <a href="http://wufan0023.javaeye.com/blog/197509#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 27 May 2008 16:39:11 +0800</pubDate>
        <link>http://wufan0023.javaeye.com/blog/197509</link>
        <guid>http://wufan0023.javaeye.com/blog/197509</guid>
      </item>
          <item>
        <title>技术来不得马虎</title>
        <author>wufan0023</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://wufan0023.javaeye.com">wufan0023</a>&nbsp;
                    链接：<a href="http://wufan0023.javaeye.com/blog/192875" style="color:red;">http://wufan0023.javaeye.com/blog/192875</a>&nbsp;
          发表时间: 2008年05月14日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          做程序员有一定的时间了，羡慕各位老大们的能力，也在拼命的学习。但是学来学去还是迷茫。虽然自己的卖力完成了工作，自己的卖力得到公司的认同。但是自己心里还是有数的。自己只是一个小鸟，离羽翼丰满还早的很。<br />&nbsp;&nbsp;&nbsp; 总结了，自己这么久的工作经历，也参看了不少同事的经历，才认识到自己不够踏实。现在网络的开放降低了程序员工作的难度，但是也带来了懒惰的情绪和不求甚解的心理。很多东西只是自己闪闪改改放在项目里面就可以了。实际上自己的能力只是个装配工。<br />&nbsp;&nbsp;&nbsp; 技术这东西真是来不得马虎。这两天仔细研究了下主流站点中的页面代码。发现自己的差距不是一般的大，为什么告诉自己这个不重要？为什么告诉自己这个用不着？事实上很多东西就是在这样的自我安慰当中放过去，很多很好的锻炼机会就这样错过了。<br />&nbsp;&nbsp;&nbsp; 最近经常接触与佛有关的东西，虽然自己也不崇拜它，但是控制自己，持之以恒的自身修为，我倒是很认同的。放在技术上真的是很实际，耐下心来研究才是出色的基础。<br />&nbsp;&nbsp;&nbsp; 一点一点来，坚持自己。<br />&nbsp;&nbsp;&nbsp; 也许是上天给个机会给我，刚开始锻炼身体去体检就检查出来脂肪肝。看来可以同时坚持锻炼下身体。
          <br/><br/>
          <span style="color:red;">
            <a href="http://wufan0023.javaeye.com/blog/192875#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 14 May 2008 11:23:38 +0800</pubDate>
        <link>http://wufan0023.javaeye.com/blog/192875</link>
        <guid>http://wufan0023.javaeye.com/blog/192875</guid>
      </item>
          <item>
        <title>IE下appendChild 无法实现此接口（在FF下可以）</title>
        <author>wufan0023</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://wufan0023.javaeye.com">wufan0023</a>&nbsp;
                    链接：<a href="http://wufan0023.javaeye.com/blog/174087" style="color:red;">http://wufan0023.javaeye.com/blog/174087</a>&nbsp;
          发表时间: 2008年03月20日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          由于报错的位置和实际出错的代码关联性不强，找了好一会才找到。<br />看下源代码：<br />父页面中，html中插入div：<br /><pre name="code" class="HTML">&lt;div id="ctTab" >&lt;/div></pre><br />在pop-up页面中插入表格：<br /><pre name="code" class="js">function ctTabInsert(){
   var ctTab = self.opener.document.getElementById('ctTab');
   ctTab.innerText = "";
   var _tab = opener.document.createElement("table");  //&lt;---引发错误位置
   getElementsByName('emails');
   var guids = document.getElementsByName('guids');
   for( var i = 0;i &lt; guids.length;i ++ ){
      var guid = guids[i].value;
	  var name = names[i].value.trim().ignoreSpaces();
	  var numOne = handset0s[i].value.trim().ignoreSpaces();
	  var numTwo = handset2s[i].value.trim().ignoreSpaces();
	  var email = emails[i].value.trim().ignoreSpaces();
	  var _trRow = _tab.insertRow(i);
	  var guidCell = _trRow.insertCell(0);
	  guidCell.innerText = guid;
	  var nameCell = _trRow.insertCell(1);
	  nameCell.innerText = name;
	  var numOneCell = _trRow.insertCell(2);
	  numOneCell.innerText = numOne;
	  var nameTwoCell = _trRow.insertCell(2);
	  nameTwoCell.innerText = numTwo;
	  var emailCell = _trRow.insertCell(2);
	  emailCell.innerText = email;
   }
  ctTab.appendChild(_tab); //&lt;---报错位置
}</pre><br />如果使用下面代码则会报IE 无法实现这个接口的错误。：<br /><pre name="code" class="java">   var _tab = document.createElement("table");//&lt;---错误代码</pre>
          <br/><br/>
          <span style="color:red;">
            <a href="http://wufan0023.javaeye.com/blog/174087#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 20 Mar 2008 13:25:45 +0800</pubDate>
        <link>http://wufan0023.javaeye.com/blog/174087</link>
        <guid>http://wufan0023.javaeye.com/blog/174087</guid>
      </item>
          <item>
        <title>finally的含义</title>
        <author>wufan0023</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://wufan0023.javaeye.com">wufan0023</a>&nbsp;
                    链接：<a href="http://wufan0023.javaeye.com/blog/159728" style="color:red;">http://wufan0023.javaeye.com/blog/159728</a>&nbsp;
          发表时间: 2008年01月27日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          finally 关键字是对 Java 异常处理模型的最佳补充。 finally 结构使代码总会执行，而不管有无异常发生。使用 finally 可以维护对象的内部状态，并可以清理非内存资源。如果没有 finally，您的代码就会很费解。比如关闭事务。正常流和异常流都要写。使用finally就没有这样的问题了。<br /><br />有一种方法可以退出 try 块而不执行 finally 块。如果代码在 try 内部执行一条 System.exit(0); 语句，则应用程序终止而不会执行 finally 执行。另一方面，如果您在 try 块执行期间拨掉电源，finally 也不会执行。）
          <br/><br/>
          <span style="color:red;">
            <a href="http://wufan0023.javaeye.com/blog/159728#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 27 Jan 2008 16:08:35 +0800</pubDate>
        <link>http://wufan0023.javaeye.com/blog/159728</link>
        <guid>http://wufan0023.javaeye.com/blog/159728</guid>
      </item>
          <item>
        <title>Tomcat 概要脑图</title>
        <author>wufan0023</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://wufan0023.javaeye.com">wufan0023</a>&nbsp;
                    链接：<a href="http://wufan0023.javaeye.com/blog/154261" style="color:red;">http://wufan0023.javaeye.com/blog/154261</a>&nbsp;
          发表时间: 2008年01月09日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <br /><p><a href="file:///C:/Documents%20and%20Settings/Administrator/Application%20Data/Windows%20Live%20Writer/PostSupportingFiles/67ca37d6-c67d-4aca-949e-b80795c8fc24/image5.png"><img src="file:///C:/Documents%20and%20Settings/Administrator/Application%20Data/Windows%20Live%20Writer/PostSupportingFiles/67ca37d6-c67d-4aca-949e-b80795c8fc24/image_thumb3.png" border="0" height="761" alt="tomcat " style="border-width: 0px" width="1024" /></a> </p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://wufan0023.javaeye.com/blog/154261#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 09 Jan 2008 11:32:33 +0800</pubDate>
        <link>http://wufan0023.javaeye.com/blog/154261</link>
        <guid>http://wufan0023.javaeye.com/blog/154261</guid>
      </item>
      </channel>
</rss>