<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>DouO&#039;s Blog</title>
	<atom:link href="http://dourok.info/feed/" rel="self" type="application/rss+xml" />
	<link>http://dourok.info</link>
	<description>非淡泊无以明志，非宁静无以致远</description>
	<lastBuildDate>Wed, 16 May 2012 22:41:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Lonely Android</title>
		<link>http://dourok.info/2012/04/29/lonely-android/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=lonely-android</link>
		<comments>http://dourok.info/2012/04/29/lonely-android/#comments</comments>
		<pubDate>Sun, 29 Apr 2012 14:44:34 +0000</pubDate>
		<dc:creator>DouO</dc:creator>
				<category><![CDATA[Coder]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[processing.js]]></category>
		<category><![CDATA[wordpress插件]]></category>

		<guid isPermaLink="false">http://dourok.info/?p=685</guid>
		<description><![CDATA[两个月前，在某博客看到Android Developer的一个Flash广告挺有趣的，可以点下Conveyor.swf看看。就想把它做成WordPress 无头像评论者的随机头像（或者叫 Identicons）应该很可爱的。 所以呢，就把它做出来了。 用了之前我在这里提过的processing.js来实现，processing.js很好玩，以后再专门来说一说。 插件的原理很简单，当用户头像载入时，先去请求gravatar有没该用户的头像，有的话就把头像显示出来完事，没有的话就根据用户的id，即邮箱的MD5码生成一个对应的Android机器人出来，这里跟gravatar生成随机头像是一样的，然后再加上个1秒钟的渐变效果。插件都是在客户端运行的，用的是客户端的CPU不会影响到服务器，但获取gravatar图片的跨域问题也挺烦的，现在还没有真正解决。另外这个插件还有个实际点的好处，因为某墙的缘故，gravatar在墙内也是经常抽风的，用这个插件就可以避免出现一片空白，而是换成一个可爱的Android机器人。用了lazyload技术，头像的动画只会在头像出现在视图（viewport）中才会触发，相对来说对页面的流畅程度的影响比较小，不过如果评论多的话，还是慎用（话说评论N多的牛人会用这么白痴的东西吗？）。 插件的具体效果可以点几下下面的框框看看： 因为是用了processingjs，还需要导入processingjs框架，而插件本身是没有提供这个框架的，所以呢装这个插件之前，推荐先装一下这个：http://www.ramoonus.nl/wordpress/processing-js/ 这个插件可以在这里下载：imandroid。 其实在用processingjs实现之前我已经在Android平台上实现了这个东东，幸好有processingjs这么像java语法的东西让我省了不少力气移植到js上来。 不浪费顺便弄了个动态壁纸（live wallpaper），到Play Store看下吧。 ©2012 "DouO's Blog". 请在遵守CC协议的前提使用该文章。]]></description>
			<content:encoded><![CDATA[<p><canvas data-processing-sources="http://dourok.info/pjs/lonelyandroid.pjs"></canvas><br />
<span id="more-685"></span><br />
两个月前，在某博客看到Android Developer的一个Flash广告挺有趣的，可以点下<a href="http://static.googleusercontent.com/external_content/untrusted_dlcp/www.android.com/zh-CN//swf/conveyor.swf"  target="_blank" title="conveyor.swf">Conveyor.swf</a>看看。就想把它做成WordPress 无头像评论者的随机头像（或者叫 <a href="http://en.wikipedia.org/wiki/Identicon" target="_blank" title="Identicon">Identicons</a>）应该很可爱的。</p>
<p>所以呢，就把它做出来了。</p>
<p>用了之前我在<a href="http://dourok.info/2011/12/before_2012/">这里</a>提过的<a href="http://processingjs.org">processing.js</a>来实现，processing.js很好玩，以后再专门来说一说。</p>
<p>插件的原理很简单，当用户头像载入时，先去请求gravatar有没该用户的头像，有的话就把头像显示出来完事，没有的话就根据用户的id，即邮箱的MD5码生成一个对应的Android机器人出来，这里跟gravatar生成随机头像是一样的，然后再加上个1秒钟的渐变效果。插件都是在客户端运行的，用的是客户端的CPU不会影响到服务器，但获取gravatar图片的跨域问题也挺烦的，现在还没有真正解决。另外这个插件还有个实际点的好处，因为某墙的缘故，gravatar在墙内也是经常抽风的，用这个插件就可以避免出现一片空白，而是换成一个可爱的Android机器人。用了lazyload技术，头像的动画只会在头像出现在视图（viewport）中才会触发，相对来说对页面的流畅程度的影响比较小，不过如果评论多的话，还是慎用（话说评论N多的牛人会用这么白痴的东西吗？）。<br />
插件的具体效果可以点几下下面的框框看看：<br />
<canvas data-processing-sources="http://dourok.info/wp-content/plugins/imandroid/js/imandroid.pjs"></canvas><br />
因为是用了processingjs，还需要导入processingjs框架，而插件本身是没有提供这个框架的，所以呢装这个插件之前，推荐先装一下这个：<a href="http://www.ramoonus.nl/wordpress/processing-js/" target="_blank">http://www.ramoonus.nl/wordpress/processing-js/</a></p>
<p>这个插件可以在这里下载：<a href="https://wordpress.org/extend/plugins/imandrod/" target="_blank">imandroid</a>。</p>
<p>其实在用processingjs实现之前我已经在Android平台上实现了这个东东，幸好有processingjs这么像java语法的东西让我省了不少力气移植到js上来。<br />
不浪费顺便弄了个动态壁纸（live wallpaper），到<a href="https://play.google.com/store/apps/details?id=info.dourok.imandroid" target="_blank">Play Store</a>看下吧。</p>
<hr style="border-top:black solid 1px" />©2012 "<a href="http://dourok.info">DouO's Blog</a>". 请在遵守<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh">CC协议</a>的前提使用该文章。<br />]]></content:encoded>
			<wfw:commentRss>http://dourok.info/2012/04/29/lonely-android/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>野花</title>
		<link>http://dourok.info/2012/04/22/wild_flower/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=wild_flower</link>
		<comments>http://dourok.info/2012/04/22/wild_flower/#comments</comments>
		<pubDate>Sun, 22 Apr 2012 14:49:15 +0000</pubDate>
		<dc:creator>DouO</dc:creator>
				<category><![CDATA[Life]]></category>

		<guid isPermaLink="false">http://dourok.info/?p=666</guid>
		<description><![CDATA[路边的野花独自开得这般灿烂，可曾有人为你驻足? 可野花从不管有没有人欣赏都照样开放。 从不向人类乞求一分一毫，如此孤高冷傲，也不近人情 我还是天真的希望，此刻它的灿烂是因为我的注目。 可惜我不懂花的语言，不敢开口，你现在是否在为我开放？ 今天真是适合踏青的好天气，蓝天白云，风轻如梦，视野开阔。可惜手机的镜头不给力，拍不出这种开阔。 ©2012 "DouO's Blog". 请在遵守CC协议的前提使用该文章。]]></description>
			<content:encoded><![CDATA[<p>路边的野花独自开得这般灿烂，可曾有人为你驻足?<br />
<a href="http://dourok.info/wp-content/uploads/2012/04/IMAG00071.jpg"><img src="http://dourok.info/wp-content/uploads/2012/04/IMAG00071.jpg" alt="" title="IMAG0007"  width="100%" height="100%" class="alignnone size-full wp-image-674" /></a><br />
<span id="more-666"></span><br />
可野花从不管有没有人欣赏都照样开放。<br />
从不向人类乞求一分一毫，如此孤高冷傲，也不近人情<a href="http://dourok.info/wp-content/uploads/2012/04/IMAG0034.jpg"><br />
<img src="http://dourok.info/wp-content/uploads/2012/04/IMAG0034.jpg" alt="" title="IMAG0034"  width="100%" height="100%" class="alignnone size-full wp-image-668" /></a><br />
我还是天真的希望，此刻它的灿烂是因为我的注目。<br />
可惜我不懂花的语言，不敢开口，你现在是否在为我开放？<a href="http://dourok.info/wp-content/uploads/2012/04/IMAG0160.jpg"><img src="http://dourok.info/wp-content/uploads/2012/04/IMAG0160.jpg" alt="" title="IMAG0160"  width="100%" height="100%" class="alignnone size-full wp-image-669" /></a></p>
<p>今天真是适合踏青的好天气，蓝天白云，风轻如梦，视野开阔。可惜手机的镜头不给力，拍不出这种开阔。<a href="http://dourok.info/wp-content/uploads/2012/04/IMAG00061.jpg"><img src="http://dourok.info/wp-content/uploads/2012/04/IMAG00061.jpg" alt="" title="IMAG0006"  width="100%" height="100%" class="alignnone size-full wp-image-682" /></a></p>
<hr style="border-top:black solid 1px" />©2012 "<a href="http://dourok.info">DouO's Blog</a>". 请在遵守<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh">CC协议</a>的前提使用该文章。<br />]]></content:encoded>
			<wfw:commentRss>http://dourok.info/2012/04/22/wild_flower/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>来除草了。。。</title>
		<link>http://dourok.info/2011/12/25/before_2012/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=before_2012</link>
		<comments>http://dourok.info/2011/12/25/before_2012/#comments</comments>
		<pubDate>Sun, 25 Dec 2011 09:07:25 +0000</pubDate>
		<dc:creator>DouO</dc:creator>
				<category><![CDATA[Life]]></category>
		<category><![CDATA[processing.js]]></category>
		<category><![CDATA[Wordpress]]></category>
		<category><![CDATA[Wordpress Theme]]></category>
		<category><![CDATA[吐槽]]></category>

		<guid isPermaLink="false">http://dourok.info/?p=636</guid>
		<description><![CDATA[终于争取到在2012前上来吐槽下，记录下对博客做的修改和一些新理解。 首先取消了分类目录，全部通过标签来做归类管理。像我这种随便吐槽的博客用分类目录，很多时候都觉的是种自我限制，相对的标签就自由许多，同时也有归类的功能。这方面不得不说Evernote很有相见之明，不过我很久没用Evernote了，听说它也是顶不住用户的压力开始支持分类管理了。至于技术文章，我把它归为笔记类，和其它笔记，摘抄都记录到我的wiki里，wiki目前还是通过分类管理的，分得细致很多，不过我觉得更合理的话应该要配合上标签，即便没有客户端和没有标签管理下DokuWiki还是完全替代了我对Evernote的使用，何况标签这个功能装个插件就有了，Wiki的自由和可扩展性是无可替代的。一直有个将dokuwiki变身为云笔记想法，主要目的本地和服务器同步文件，还有Web编辑器太弱了，想通过Emacs来做桌面客户端，再来个Android App，加上一些自己常用网站的接口插件，就差不多了。我已经启动这个项目很久了（见wiki-note），不过一直没有动工过，果然是拖延症患者吧。 取消了分类目录，我就希望博客更整洁些，所以决定采用单栏模板让文章内容的空间大一些。但苦于找不到比较入眼的单栏主题，无奈选择自己看教程做，本想基于twentyten来改的，无意间发现 CriticalZero这个站，它的设计令我耳目一新，特别是头部用条斜线来切割页面，相当大胆，用的好的话就是小清新，用不好的话就像眼前这个网站一样-_-(纯粹213需要，无意贬低原作者)。虽然他页面内容的排版也漂亮，但文章的空间太小不适合我的需求。所以我还是采用传统的纵向排列，这样保证了文章有足够大的宽度，看起来舒服些。其它细节我也搬了不少过来，再加上一些从其它主题搬过来的设计和来自 Gentleface 的图标、乱来的配色，不过 Web Colors 真的很有帮助。就这样左抄抄右抄抄，像我这样的前端苦手也能完成一款wordpress主题。 我的第一款wordpress主题就叫做BetaD吧。BetaD是twentyten（wordpress自带主题）的子主题（child theme），设计主要来自 CriticalZero ，Copy的太多都不好意思说是参考了。目前是dirty又buggy，只在Chrome和Firefox下测试过，我自己发现的就有不少bug，也没要提供任何可自定制的接口，下次再修复吧。有兴趣的同学到这里看下：https://github.com/dourokinga/BetaD 另外，不知大家有发现没，这个主题的背景是动态生成，在研究代码是时候，发现了相当酷的框架processing.js，是用来做html5交互动画的。这个背景就是用这个框架生成的，看起来十分强大的样子，一定要来研究下。 ©2012 "DouO's Blog". 请在遵守CC协议的前提使用该文章。]]></description>
			<content:encoded><![CDATA[<p>终于争取到在2012前上来吐槽下，记录下对博客做的修改和一些新理解。</p>
<p>首先取消了分类目录，全部通过标签来做归类管理。像我这种随便吐槽的博客用分类目录，很多时候都觉的是种自我限制，相对的标签就自由许多，同时也有归类的功能。这方面不得不说Evernote很有相见之明，不过我很久没用Evernote了，听说它也是顶不住用户的压力开始支持分类管理了。至于技术文章，我把它归为笔记类，和其它笔记，摘抄都记录到我的wiki里，wiki目前还是通过分类管理的，分得细致很多，不过我觉得更合理的话应该要配合上标签，即便没有客户端和没有标签管理下DokuWiki还是完全替代了我对Evernote的使用，何况标签这个功能装个插件就有了，Wiki的自由和可扩展性是无可替代的。一直有个将dokuwiki变身为云笔记想法，主要目的本地和服务器同步文件，还有Web编辑器太弱了，想通过Emacs来做桌面客户端，再来个Android App，加上一些自己常用网站的接口插件，就差不多了。我已经启动这个项目很久了（见<a href="http://code.google.com/p/wiki-note/">wiki-note</a>），不过一直没有动工过，果然是拖延症患者吧。</p>
<p>取消了分类目录，我就希望博客更整洁些，所以决定采用单栏模板让文章内容的空间大一些。但苦于找不到比较入眼的单栏主题，无奈选择自己看教程做，本想基于twentyten来改的，无意间发现 <a href="http://criticalzero.co.uk/ ">CriticalZero</a>这个站，它的设计令我耳目一新，特别是头部用条斜线来切割页面，相当大胆，用的好的话就是小清新，用不好的话就像眼前这个网站一样-_-(纯粹213需要，无意贬低原作者)。虽然他页面内容的排版也漂亮，但文章的空间太小不适合我的需求。所以我还是采用传统的纵向排列，这样保证了文章有足够大的宽度，看起来舒服些。其它细节我也搬了不少过来，再加上一些从其它主题搬过来的设计和来自 <a href="http://gentleface.com/free_icon_set.html">Gentleface</a> 的图标、乱来的配色，不过 <a href="http://www.css-html.net/web_colors/">Web Colors</a> 真的很有帮助。就这样左抄抄右抄抄，像我这样的前端苦手也能完成一款wordpress主题。</p>
<p>我的第一款wordpress主题就叫做BetaD吧。<a href="https://github.com/dourokinga/BetaD">BetaD</a>是twentyten（wordpress自带主题）的子主题（child theme），设计主要来自 <a href="http://criticalzero.co.uk/ ">CriticalZero</a> ，Copy的太多都不好意思说是参考了。目前是dirty又buggy，只在Chrome和Firefox下测试过，我自己发现的就有不少bug，也没要提供任何可自定制的接口，下次再修复吧。有兴趣的同学到这里看下：<a href="https://github.com/dourokinga/BetaD">https://github.com/dourokinga/BetaD</a></p>
<p>另外，不知大家有发现没，这个主题的背景是动态生成，在研究代码是时候，发现了相当酷的框架<a href="http://processingjs.org">processing.js</a>，是用来做html5交互动画的。这个背景就是用这个框架生成的，看起来十分强大的样子，一定要来研究下。</p>
<hr style="border-top:black solid 1px" />©2012 "<a href="http://dourok.info">DouO's Blog</a>". 请在遵守<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh">CC协议</a>的前提使用该文章。<br />]]></content:encoded>
			<wfw:commentRss>http://dourok.info/2011/12/25/before_2012/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>在Netbeans上查看Android源码</title>
		<link>http://dourok.info/2011/10/10/browse_android_sources_on_netbeans/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=browse_android_sources_on_netbeans</link>
		<comments>http://dourok.info/2011/10/10/browse_android_sources_on_netbeans/#comments</comments>
		<pubDate>Sun, 09 Oct 2011 19:58:00 +0000</pubDate>
		<dc:creator>DouO</dc:creator>
				<category><![CDATA[Coder]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[NBAdroid]]></category>
		<category><![CDATA[Netbeans]]></category>

		<guid isPermaLink="false">http://dourok.info/?p=606</guid>
		<description><![CDATA[Netbeans7.1终于有像Eclipse一样的Attach Sources按钮，可以为android.jar附加源码了。虽然现在Netbeans 7.1 还处在测试阶段，但这个功能太重要了，迫不及待要去尝鲜，不过其实现在也足够稳定了。 先下载Netbeans 7.1 beta，然后在这里：http://adt-addons.googlecode.com/svn/trunk/source/com.android.ide.eclipse.source.update/plugins/ 可以下载到打包好android各版本的源码，这是个jar档案需要解压出来。 另外，如果已安装有旧版本的netbeans，如7.0；需要注意一个问题，如Bug 200698 里 jn0101@netbeans.org 的描述。如果7.1和旧版的netbeans共用一个userdir可能会导致”Attach Sources”按钮失效。我试过了确实会这样（linux下）。解决方法可以用&#8211;userdir给netbeans 7.1重新指定一个新userdir。不过，我是直接把.netbeans文件删掉，当然有先备份，然后，先配置好7.1的nbandroid，然后把sources.zip附到相应的android.jar。再把备份的7.0拷回来。可以把7.0的一些config拷给7.1，如：Editors和Keymaps等等。这样两个版本都可以正常工作了。 另外，意外的是在debug下还能工作的挺好的。 NBANDROID-71基本可以算解决了。 见此,如何在Netbeans上配置Android开发环境 ©2012 "DouO's Blog". 请在遵守CC协议的前提使用该文章。]]></description>
			<content:encoded><![CDATA[<p>Netbeans7.1终于有像Eclipse一样的Attach Sources按钮，可以为android.jar附加源码了。虽然现在Netbeans 7.1 还处在测试阶段，但这个功能太重要了，迫不及待要去尝鲜，不过其实现在也足够稳定了。<br />
<a href="http://dourok.info/wp-content/uploads/2010/05/attach_sources.png"><img src="http://dourok.info/wp-content/uploads/2010/05/attach_sources.png" alt="" title="attach_sources" width="442" height="374" class="alignnone size-full wp-image-602" /></a><br />
先下载<a href="http://netbeans.org/community/releases/71/">Netbeans 7.1 beta</a>，然后在这里：<a href="http://adt-addons.googlecode.com/svn/trunk/source/com.android.ide.eclipse.source.update/plugins/">http://adt-addons.googlecode.com/svn/trunk/source/com.android.ide.eclipse.source.update/plugins/</a> 可以下载到打包好android各版本的源码，这是个jar档案需要解压出来。<br />
<span id="more-606"></span><br />
另外，如果已安装有旧版本的netbeans，如7.0；需要注意一个问题，如<a href="http://netbeans.org/bugzilla/show_bug.cgi?id=200698">Bug 200698 </a>里  jn0101@netbeans.org 的描述。如果7.1和旧版的netbeans共用一个userdir可能会导致”Attach Sources”按钮失效。我试过了确实会这样（linux下）。解决方法可以用<a href="http://wiki.netbeans.org/FaqAlternateUserdir">&#8211;userdir</a>给netbeans 7.1重新指定一个新userdir。不过，我是直接把.netbeans文件删掉，当然有先备份，然后，先配置好7.1的nbandroid，然后把sources.zip附到相应的android.jar。再把备份的7.0拷回来。可以把7.0的一些config拷给7.1，如：Editors和Keymaps等等。这样两个版本都可以正常工作了。<br />
<a href="http://dourok.info/wp-content/uploads/2010/05/view_sources.png"><img src="http://dourok.info/wp-content/uploads/2010/05/view_sources.png" alt="" title="view_sources" width="578" height="418" class="alignnone size-full wp-image-603" /></a></p>
<p>另外，意外的是在debug下还能工作的挺好的。<br />
<a href="http://dourok.info/wp-content/uploads/2010/05/debug_view.png"><img src="http://dourok.info/wp-content/uploads/2010/05/debug_view.png" alt="" title="debug_view" width="686" height="666" class="alignnone size-full wp-image-604" /></a></p>
<p><a href="http://kenai.com/jira/browse/NBANDROID-71">NBANDROID-71</a>基本可以算解决了。</p>
<p>见此,如何<a href="http://dourok.info/2010/05/%e5%9c%a8netbeans%e4%b8%8a%e9%85%8d%e7%bd%aeandroid%e5%bc%80%e5%8f%91%e7%8e%af%e5%a2%83/" title="在Netbeans上配置Android开发环境">在Netbeans上配置Android开发环境</a></p>
<hr style="border-top:black solid 1px" />©2012 "<a href="http://dourok.info">DouO's Blog</a>". 请在遵守<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh">CC协议</a>的前提使用该文章。<br />]]></content:encoded>
			<wfw:commentRss>http://dourok.info/2011/10/10/browse_android_sources_on_netbeans/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>修复了 Lyrics Grabber2 的千千静听歌词抓取脚本</title>
		<link>http://dourok.info/2011/08/08/fixed_ttplayer_lrc_py/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=fixed_ttplayer_lrc_py</link>
		<comments>http://dourok.info/2011/08/08/fixed_ttplayer_lrc_py/#comments</comments>
		<pubDate>Sun, 07 Aug 2011 19:40:07 +0000</pubDate>
		<dc:creator>DouO</dc:creator>
				<category><![CDATA[Coder]]></category>
		<category><![CDATA[Otaku]]></category>
		<category><![CDATA[foobar2000]]></category>
		<category><![CDATA[Lyrics Grabber2]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[歌词搜索]]></category>

		<guid isPermaLink="false">http://dourok.info/?p=571</guid>
		<description><![CDATA[之前修改过现在查词失败的同学请点这里 Lyrics Grabber2 可以说我理想中的歌曲下载插件，主要是它可以批量抓取更新歌词，又可以自定义抓取脚本方便扩展(见此HowToMakeProviderInPython)，实在强大。不过还是有一些不足，比如找到的歌词没有给出来源（Provider），歌词服务器（Provier）不能更改优先级，还有就是出现多个歌词的匹配问题，既有多个服务器的，也有一个服务器的多个歌词的，希望能增加人工选择的选项。不过 Lyrics Grabber2刚好一年没更新了，再更新实在希望不大。 再者，现在Lyrics Grabber2里面的千千静听歌词抓取脚本（TTPlayer(LRC).py）是用不了的。我了解一下，把bug总结如下： bug_1:36行 导致搜索失败的主要原因，现在千千静听搜索歌词的服务器变了 bug_2:103行 另一个导致搜索失败的原因，用来生成code的字符串应该用utf-8编码，而用minidom.parseString出来的字符串已经是utf-16le的了. bug_3:114行 这一行应该是打错了. 条件应该是 c &#62;= 0&#215;80: bug_4:42行 同样是编码问题，导致Levenshtein算法失效，因为比对的是两个不同编码的字符串。 修复完bug后，就可以成功查词了。但是结果并不理想。 由上图可以看出是，英文和简体没压力但繁（正）体中文就不行了。显然还需对title做些处理。通过对千千静听进行测试，发现千千静听对查询串的处理远不止 71 72 73 所在的那样。 大概做了下面这些过滤： 英文转小写 去括号，大中小还有全角的小括号 去除半角特殊符号，空格，逗号，etc。 去除全角特殊符号 繁（正）体转换为简体 繁（正）体转换为简体，找不到好的现成方案（针对unicode字符集uft-8编码的）。只能动用谷歌翻译的api了。没想到谷歌翻译倒工作的很好。不过毕竟是多一个网络请求，建议不需要的时候可以把它注释掉，以加快查询速度。其他过滤功能也可以根据情况去掉，已加强效率。FYI:脚本更改后立即生效，无须重启foobar2000的。 针对这些，增加了下面的新方法 def QianQianStringFilter&#40;self,string&#41;: s = string # 英文转小写 s = s.lower&#40;&#41; # 去括号，大中小还有全角的小括号 s = re.sub&#40;'\(.*?\)&#124;\[.*?]&#124;{.*?}&#124;（.*?）', '', s&#41;; # 去除半角特殊符号，空格，逗号，etc。 s = re.sub&#40;'[ [...]]]></description>
			<content:encoded><![CDATA[<p>之前修改过现在查词失败的同学请点<a href="#attention">这里</a></p>
<p><a href="http://code.google.com/p/lyricsgrabber2/">Lyrics Grabber2</a> 可以说我理想中的歌曲下载插件，主要是它可以批量抓取更新歌词，又可以自定义抓取脚本方便扩展(见<a href="http://code.google.com/p/lyricsgrabber/wiki/HowToMakeProviderInPython">此HowToMakeProviderInPython</a>)，实在强大。不过还是有一些不足，比如找到的歌词没有给出来源（Provider），歌词服务器（Provier）不能更改优先级，还有就是出现多个歌词的匹配问题，既有多个服务器的，也有一个服务器的多个歌词的，希望能增加人工选择的选项。不过 Lyrics Grabber2刚好一年没更新了，再更新实在希望不大。</p>
<p>再者，现在Lyrics Grabber2里面的千千静听歌词抓取脚本（TTPlayer(LRC).py）是用不了的。我了解一下，把bug总结如下：</p>
<p>bug_1:<a href="http://code.google.com/p/lyricsgrabber2/source/browse/trunk/foo_lyricsgrabber2/dist/pygrabber/scripts/TTPlayer(LRC).py#36">36行</a></p>
<p>导致搜索失败的主要原因，现在千千静听搜索歌词的服务器变了<br />
<span id="more-571"></span></p>
<p>bug_2:<a href="http://code.google.com/p/lyricsgrabber2/source/browse/trunk/foo_lyricsgrabber2/dist/pygrabber/scripts/TTPlayer(LRC).py#103">103行</a><br />
另一个导致搜索失败的原因，用来生成code的字符串应该用utf-8编码，而用minidom.parseString出来的字符串已经是utf-16le的了.</p>
<p>bug_3:<a href="http://code.google.com/p/lyricsgrabber2/source/browse/trunk/foo_lyricsgrabber2/dist/pygrabber/scripts/TTPlayer(LRC).py#144">114行</a><br />
这一行应该是打错了. 条件应该是 c &gt;= 0&#215;80:</p>
<p>bug_4:<a href="http://code.google.com/p/lyricsgrabber2/source/browse/trunk/foo_lyricsgrabber2/dist/pygrabber/scripts/TTPlayer(LRC).py#42">42行</a><br />
同样是编码问题，导致Levenshtein算法失效，因为比对的是两个不同编码的字符串。</p>
<p>修复完bug后，就可以成功查词了。但是结果并不理想。<br />
<a href="http://dourok.info/wp-content/uploads/2011/08/t2.png"><img class="alignnone size-full wp-image-577" title="t2" src="http://dourok.info/wp-content/uploads/2011/08/t2.png" alt="" width="716" height="425" /></a></p>
<p>由上图可以看出是，英文和简体没压力但繁（正）体中文就不行了。显然还需对title做些处理。通过对千千静听进行测试，发现千千静听对查询串的处理远不止 <a href="http://code.google.com/p/lyricsgrabber2/source/browse/trunk/foo_lyricsgrabber2/dist/pygrabber/scripts/TTPlayer(LRC).py#71">71</a> <a href="http://code.google.com/p/lyricsgrabber2/source/browse/trunk/foo_lyricsgrabber2/dist/pygrabber/scripts/TTPlayer(LRC).py#72">72</a> <a href="http://code.google.com/p/lyricsgrabber2/source/browse/trunk/foo_lyricsgrabber2/dist/pygrabber/scripts/TTPlayer(LRC).py#73">73</a> 所在的那样。<br />
大概做了下面这些过滤：</p>
<ul>
<li>英文转小写</li>
<li>去括号，大中小还有全角的小括号</li>
<li>去除半角特殊符号，空格，逗号，etc。</li>
<li>去除全角特殊符号</li>
<li>繁（正）体转换为简体</li>
</ul>
<p>繁（正）体转换为简体，找不到好的现成方案（针对unicode字符集uft-8编码的）。只能动用谷歌翻译的api了。没想到谷歌翻译倒工作的很好。不过毕竟是多一个网络请求，建议不需要的时候可以把它注释掉，以加快查询速度。其他过滤功能也可以根据情况去掉，已加强效率。FYI:脚本更改后立即生效，无须重启foobar2000的。</p>
<p>针对这些，增加了下面的新方法</p>
<div class="codecolorer-container python railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">def</span> QianQianStringFilter<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span><span style="color: #dc143c;">string</span><span style="color: black;">&#41;</span>:<br />
s <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">string</span><br />
<span style="color: #808080; font-style: italic;"># 英文转小写</span><br />
s <span style="color: #66cc66;">=</span> s.<span style="color: black;">lower</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
<span style="color: #808080; font-style: italic;"># 去括号，大中小还有全角的小括号</span><br />
s <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">sub</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'<span style="color: #000099; font-weight: bold;">\(</span>.*?<span style="color: #000099; font-weight: bold;">\)</span>|<span style="color: #000099; font-weight: bold;">\[</span>.*?]|{.*?}|（.*?）'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">''</span><span style="color: #66cc66;">,</span> s<span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span><br />
<span style="color: #808080; font-style: italic;"># 去除半角特殊符号，空格，逗号，etc。</span><br />
s <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">sub</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'[ -/:-@[-`{-~]+'</span><span style="color: #66cc66;">,</span> <span style="color: #483d8b;">''</span><span style="color: #66cc66;">,</span> s<span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span><br />
<span style="color: #808080; font-style: italic;"># 繁（正）体转换为简体</span><br />
s <span style="color: #66cc66;">=</span> translate<span style="color: black;">&#40;</span>s<span style="color: #66cc66;">,</span><span style="color: #483d8b;">'zh-tw'</span><span style="color: #66cc66;">,</span><span style="color: #483d8b;">'zh-cn'</span><span style="color: black;">&#41;</span><br />
s <span style="color: #66cc66;">=</span> <span style="color: #008000;">unicode</span><span style="color: black;">&#40;</span>s<span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'utf_8'</span><span style="color: black;">&#41;</span><br />
<span style="color: #808080; font-style: italic;"># 去除全角特殊符号</span><br />
s <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">re</span>.<span style="color: black;">sub</span><span style="color: black;">&#40;</span>u<span style="color: #483d8b;">'[<span style="color: #000099; font-weight: bold;">\u</span>2014<span style="color: #000099; font-weight: bold;">\u</span>2018<span style="color: #000099; font-weight: bold;">\u</span>201c<span style="color: #000099; font-weight: bold;">\u</span>2026<span style="color: #000099; font-weight: bold;">\u</span>3001<span style="color: #000099; font-weight: bold;">\u</span>3002<span style="color: #000099; font-weight: bold;">\u</span>300a<span style="color: #000099; font-weight: bold;">\u</span>300b<span style="color: #000099; font-weight: bold;">\u</span>300e<span style="color: #000099; font-weight: bold;">\u</span>300f<span style="color: #000099; font-weight: bold;">\u</span>3010<span style="color: #000099; font-weight: bold;">\u</span>3011<span style="color: #000099; font-weight: bold;">\u</span>30fb<span style="color: #000099; font-weight: bold;">\u</span>ff01<span style="color: #000099; font-weight: bold;">\u</span>ff08<span style="color: #000099; font-weight: bold;">\u</span>ff09<span style="color: #000099; font-weight: bold;">\u</span>ff0c<span style="color: #000099; font-weight: bold;">\u</span>ff1a<span style="color: #000099; font-weight: bold;">\u</span>ff1b<span style="color: #000099; font-weight: bold;">\u</span>ff1f<span style="color: #000099; font-weight: bold;">\u</span>ff5e<span style="color: #000099; font-weight: bold;">\u</span>ffe5]+'</span><span style="color: #66cc66;">,</span><span style="color: #483d8b;">''</span><span style="color: #66cc66;">,</span>s<span style="color: black;">&#41;</span><br />
<span style="color: #ff7700;font-weight:bold;">return</span> s</div></div>
<div class="codecolorer-container python railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">def</span> translate<span style="color: black;">&#40;</span>text<span style="color: #66cc66;">,</span>lang_from<span style="color: #66cc66;">,</span>lang_to<span style="color: black;">&#41;</span>:<br />
url <span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">'http://ajax.googleapis.com/ajax/services/language/translate?'</span> +<br />
<span style="color: #483d8b;">'v=1.0&amp;q='</span>+<span style="color: #dc143c;">urllib</span>.<span style="color: black;">quote</span><span style="color: black;">&#40;</span>text<span style="color: black;">&#41;</span>+<span style="color: #483d8b;">'&amp;langpair='</span>+lang_from+<span style="color: #483d8b;">'%7C'</span>+lang_to<span style="color: black;">&#41;</span><br />
json <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">urllib</span>.<span style="color: black;">urlopen</span><span style="color: black;">&#40;</span>url<span style="color: black;">&#41;</span>.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
<span style="color: #808080; font-style: italic;"># return json;</span><br />
p <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">re</span>.<span style="color: #008000;">compile</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'&quot;translatedText&quot;:&quot;(.+?)&quot;'</span><span style="color: black;">&#41;</span><br />
m <span style="color: #66cc66;">=</span> p.<span style="color: black;">search</span><span style="color: black;">&#40;</span>json<span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span><br />
<span style="color: #ff7700;font-weight:bold;">return</span> m.<span style="color: black;">group</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span></div></div>
<p><a name="attention"></a><strong>注意:</strong>谷歌翻译的api已经过期了，会导致查词失败，新的翻译api又要收费还很贵，见<a href="http://code.google.com/apis/language/translate/v2/pricing.html">http://code.google.com/apis/language/translate/v2/pricing.html</a>，坑爹呢这是。幸好还有Bing做后援。虽然不给力，但简繁转换还是没问题的。下面的代码改用Bing的翻译服务：</p>
<div class="codecolorer-container python railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">def</span> translate<span style="color: black;">&#40;</span>text<span style="color: #66cc66;">,</span>lang_from<span style="color: #66cc66;">,</span>lang_to<span style="color: black;">&#41;</span>:<br />
url <span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span><span style="color: #483d8b;">'http://api.microsofttranslator.com/V2/Ajax.svc/Translate?'</span> +<br />
<span style="color: #483d8b;">'appId=DE2A1CAA235EB52E611BC1243F16E4D301BB600E'</span> +<br />
<span style="color: #483d8b;">'&amp;from='</span>+ lang_from +<span style="color: #483d8b;">'&amp;to='</span>+ lang_to +<br />
<span style="color: #483d8b;">'&amp;text='</span>+<span style="color: #dc143c;">urllib</span>.<span style="color: black;">quote</span><span style="color: black;">&#40;</span>text<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><br />
json <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">urllib</span>.<span style="color: black;">urlopen</span><span style="color: black;">&#40;</span>url<span style="color: black;">&#41;</span>.<span style="color: black;">read</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span><br />
p <span style="color: #66cc66;">=</span> <span style="color: #dc143c;">re</span>.<span style="color: #008000;">compile</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'&quot;(.+?)&quot;'</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;">#對應必應</span><br />
m <span style="color: #66cc66;">=</span> p.<span style="color: black;">search</span><span style="color: black;">&#40;</span>json<span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span><br />
<span style="color: #ff7700;font-weight:bold;">return</span> m.<span style="color: black;">group</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span><span style="color: #66cc66;">;</span></div></div>
<p>这样，大部分流行歌曲特别是华人音乐，都可以表示毫无压力。<br />
<a href="http://dourok.info/wp-content/uploads/2011/08/t1.png"><img class="alignnone size-full wp-image-576" title="t1" src="http://dourok.info/wp-content/uploads/2011/08/t1.png" alt="" width="676" height="415" /></a><br />
千千静听的大部分歌词都是简体的……</p>
<p>歌名特殊符号的也能识别了<br />
<a href="http://dourok.info/wp-content/uploads/2011/08/t3.png"><img class="alignnone size-full wp-image-579" title="t3" src="http://dourok.info/wp-content/uploads/2011/08/t3.png" alt="" width="694" height="496" /></a></p>
<p><a href="http://dourok.info/wp-content/uploads/2011/08/t2_.png"><img class="alignnone size-full wp-image-578" title="t2_" src="http://dourok.info/wp-content/uploads/2011/08/t2_.png" alt="" width="690" height="429" /></a><br />
You Ain&#8217;t Goin Nowhere在千千静听里面也是Fault。</p>
<p>但是这样并不完美，毕竟是黑盒测试，比如 中千千静听的<strong>後</strong>(/u8C5F)字并没有转换到<strong>后 </strong>，如下图：</p>
<p><a href="http://dourok.info/wp-content/uploads/2011/08/t4.png"><img class="alignnone size-full wp-image-580" title="t4" src="http://dourok.info/wp-content/uploads/2011/08/t4.png" alt="" width="696" height="482" /></a></p>
<p><strong>最後の放課後</strong> 在千千静听中可以找到，<strong>花は桜 君は美し -instrumental-</strong> 则同样找不到</p>
<p>不过目前也就这能做到这样。</p>
<p>改好的脚本在此:<a href="http://code.dourok.info/python/foo_lyricsgrabber2_scripts/TTPlayer(LRC).py">TTPlayer(LRC).py</a></p>
<p>另外，乐辞的脚本也是不行的，顺手也改好了。<a title="Lyricist(LRC).py" href="http://code.dourok.info/python/foo_lyricsgrabber2_scripts/Lyricist(LRC).py">Lyricist(LRC).py</a></p>
<p>btw：千千静听的歌词库，只要是热门的，流行的，出名的歌曲都挺全的，不知是从哪里来的。</p>
<p>&nbsp;</p>
<hr style="border-top:black solid 1px" />©2012 "<a href="http://dourok.info">DouO's Blog</a>". 请在遵守<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh">CC协议</a>的前提使用该文章。<br />]]></content:encoded>
			<wfw:commentRss>http://dourok.info/2011/08/08/fixed_ttplayer_lrc_py/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>迷宫生成算法</title>
		<link>http://dourok.info/2011/07/14/maze_generation_algorithm/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=maze_generation_algorithm</link>
		<comments>http://dourok.info/2011/07/14/maze_generation_algorithm/#comments</comments>
		<pubDate>Thu, 14 Jul 2011 08:23:34 +0000</pubDate>
		<dc:creator>DouO</dc:creator>
				<category><![CDATA[Coder]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[图论]]></category>
		<category><![CDATA[迷宫]]></category>

		<guid isPermaLink="false">http://dourok.info/?p=537</guid>
		<description><![CDATA[迷宫,大家都在知道是什么吧.一种标准的迷宫可以是像下图这样的结构, 一个矩形空间上,布置出错综复杂的墙,本文讨论的主要是这种结构的简单迷宫.可以想象出在下图这样的结构里,推倒某些墙壁.来生成迷宫.当然墙不是随便可以推倒的. 这样的结构姑且称为完全方格图(square grid graph)吧.从图论角度上看,这样的结构等同于下面这张图.圆圈表示顶点,线段表示边. 而最上面的迷宫,就可以认为上面那张完全方格图的生成子图,仔细观察上面的迷宫,就会发现无论从那里开始走,都可以到达迷宫中的任意一个地方(顶点).用图论术语来讲也就是说迷宫它还必须是一个连通图,这个可以理解,迷宫里到达不了的地方实际上没有意义. 另外继续观察还可以发现,无论你从那个地方出发,只要不往回走,就永远也回不到原来出发的地方.也就是不会绕圈圈.图论上说这叫做没有回路.当然回路这个可以有,有回路的迷宫更让人迷惑也可以更好玩,但这还得取决于回路如何设计.简单起见,这里生成的迷宫没有回路.就这两个特性,就可以给这种迷宫下定义了:完全方格图的没有回路连通生成子图.也就是完全方格图的生成树. 图的生成树算法那就相当广泛了,一次广度优先搜索(BFS)或深度优先搜索(DFS),都可以构建出图的生成子树.只要让选择下一个顶点的策略随机化,每次搜索出来的就是一个随机生成树也就是随机生成的迷宫.但是BFS生成出来的结果由于其他顶点相对于起始顶点的深度不变,导致迷宫随机性不够理想,下面提到的Prim算法算是一种对BFS的不错改进.DFS生成的过程比较生动就像是在挖地道一样推倒一面面墙.用来生成迷宫就比较直观也比较适合. 还有经典的最小生成树算法,Kruskal和Prim,都可以用来生成迷宫.当然完全方格图所有边都是单位权值的.所有生成树都是最小的,要运用Kruskal和Prim要做的改变就是将原来已以小优先的选择边策略改为随机选取.出来的是一个随机生成树. 当然上面的算法都是基于图论的,在维基百科里还提到另外一种不用图论的算法,比较有趣,叫递归分割法(Recursive division method),我喜欢叫你建墙我挖洞法,从名字就可以看出这是一种分治法,基本的策略就是,在一个空间里建立两面相交墙,形成四个较小的空间,然后再挖上三个洞.然后再对四个较小的空间执行相同的处理.直至每个空间的长或宽为单元大小不可再分割为止.这种方法效率比较高,由于是分治法也比较适合用分布式运算.这种方法生成出来的迷宫也是符合上面所提到的连通性和没有回路两个特点,可以用递归法简单证明下,由于两面墙隔出了四个空间,开三个洞刚好使每个空间可以互相连通,且没有回路,如果从一个空间到达另一个空间必定到达该空间的其中一个子空间,也就可以到达其他三个子空间.以此类推就到达迷宫上的每一个空间.不够生成出来的迷宫却较为简单,直路太多不够扭曲. 我用html5实现一个迷宫生成算法的演示,分别针对DFS,Kruskal,Prim和最后的分治法.可以去玩一下. 抱怨一下javascript,绘画速度还是不够快,对于大一点的迷宫必须用脏矩形重绘,才能保证速度.不够画出来的效果却不咋地. 至于这种迷宫的走法,一个DFS就可以很好地解决了. 当然实际设计出迷宫不像是这些算法这么简单的,正如谁谁谁所说的 “迷宫设计不仅是线条和图案的组合，要有娱乐性、装饰性，还要考虑那些穿越迷宫者的感受，那样才趣味无穷” 有空再考虑下其他类型迷宫的生成算法. 未完待续&#8230; 参考: http://en.wikipedia.org/wiki/Maze_generation_algorithm http://en.wikipedia.org/wiki/Maze ©2012 "DouO's Blog". 请在遵守CC协议的前提使用该文章。]]></description>
			<content:encoded><![CDATA[<p>迷宫,大家都在知道是什么吧.一种标准的迷宫可以是像下图这样的结构,</p>
<p><a href="http://dourok.info/wp-content/uploads/2011/07/maze01.png"><img class="alignnone size-full wp-image-556" title="maze01" src="http://dourok.info/wp-content/uploads/2011/07/maze01.png" alt="" width="412" height="415" /></a></p>
<p>一个矩形空间上,布置出错综复杂的墙,本文讨论的主要是这种结构的简单迷宫.可以想象出在下图这样的结构里,推倒某些墙壁.来生成迷宫.当然墙不是随便可以推倒的.</p>
<p><a href="http://dourok.info/wp-content/uploads/2011/07/maze3.png"><img class="alignnone size-full wp-image-558" title="maze3" src="http://dourok.info/wp-content/uploads/2011/07/maze3.png" alt="" width="412" height="411" /></a></p>
<p><span id="more-537"></span><br />
这样的结构姑且称为完全方格图(square grid graph)吧.从图论角度上看,这样的结构等同于下面这张图.圆圈表示顶点,线段表示边.</p>
<p><a href="http://dourok.info/wp-content/uploads/2011/07/maze2.png"><img class="alignnone size-full wp-image-557" title="maze2" src="http://dourok.info/wp-content/uploads/2011/07/maze2.png" alt="" width="394" height="391" /></a></p>
<p>而最上面的迷宫,就可以认为上面那张完全方格图的<a href="http://zh.wikipedia.org/wiki/%E5%9B%BE#.E5.9F.BA.E6.9C.AC.E6.9C.AF.E8.AF.AD">生成子图</a>,仔细观察上面的迷宫,就会发现无论从那里开始走,都可以到达迷宫中的任意一个地方(顶点).用图论术语来讲也就是说迷宫它还必须是一个<a href="http://zh.wikipedia.org/wiki/%E8%BF%9E%E9%80%9A%E5%9B%BE">连通图</a>,这个可以理解,迷宫里到达不了的地方实际上没有意义.</p>
<p>另外继续观察还可以发现,无论你从那个地方出发,只要不往回走,就永远也回不到原来出发的地方.也就是不会绕圈圈.图论上说这叫做没有回路.当然回路这个可以有,有回路的迷宫更让人迷惑也可以更好玩,但这还得取决于回路如何设计.简单起见,这里生成的迷宫没有回路.就这两个特性,就可以给这种迷宫下定义了:完全方格图的没有回路连通生成子图.也就是完全方格图的<a href="http://zh.wikipedia.org/zh-cn/%E6%A0%91_(%E5%9B%BE%E8%AE%BA)#.E5.AE.9A.E4.B9.89">生成树</a>.</p>
<p>图的生成树算法那就相当广泛了,一次广度优先搜索(BFS)或深度优先搜索(DFS),都可以构建出图的生成子树.只要让选择下一个顶点的策略随机化,每次搜索出来的就是一个随机生成树也就是随机生成的迷宫.但是BFS生成出来的结果由于其他顶点相对于起始顶点的深度不变,导致迷宫随机性不够理想,下面提到的Prim算法算是一种对BFS的不错改进.DFS生成的过程比较生动就像是在挖地道一样推倒一面面墙.用来生成迷宫就比较直观也比较适合.</p>
<p>还有经典的最小生成树算法,Kruskal和Prim,都可以用来生成迷宫.当然完全方格图所有边都是单位权值的.所有生成树都是最小的,要运用Kruskal和Prim要做的改变就是将原来已以小优先的选择边策略改为随机选取.出来的是一个随机生成树.</p>
<p>当然上面的算法都是基于图论的,在维基百科里还提到另外一种不用图论的算法,比较有趣,叫递归分割法(Recursive division method),我喜欢叫你建墙我挖洞法,从名字就可以看出这是一种分治法,基本的策略就是,在一个空间里建立两面相交墙,形成四个较小的空间,然后再挖上三个洞.然后再对四个较小的空间执行相同的处理.直至每个空间的长或宽为单元大小不可再分割为止.这种方法效率比较高,由于是分治法也比较适合用分布式运算.这种方法生成出来的迷宫也是符合上面所提到的连通性和没有回路两个特点,可以用递归法简单证明下,由于两面墙隔出了四个空间,开三个洞刚好使每个空间可以互相连通,且没有回路,如果从一个空间到达另一个空间必定到达该空间的其中一个子空间,也就可以到达其他三个子空间.以此类推就到达迷宫上的每一个空间.不够生成出来的迷宫却较为简单,直路太多不够扭曲.</p>
<p>我用html5实现一个<a href="http://tools.dourok.info/mazegame/mazegame.html">迷宫生成算法的演示</a>,分别针对DFS,Kruskal,Prim和最后的分治法.可以去玩一下.</p>
<p>抱怨一下javascript,绘画速度还是不够快,对于大一点的迷宫必须用脏矩形重绘,才能保证速度.不够画出来的效果却不咋地.</p>
<p>至于这种迷宫的走法,一个DFS就可以很好地解决了.</p>
<p>当然实际设计出迷宫不像是这些算法这么简单的,正如谁谁谁所说的</p>
<p>“迷宫设计不仅是线条和图案的组合，要有娱乐性、装饰性，还要考虑那些穿越迷宫者的感受，那样才趣味无穷”</p>
<p>有空再考虑下其他类型迷宫的生成算法.</p>
<p>未完待续&#8230;</p>
<p>参考:</p>
<p>http://en.wikipedia.org/wiki/Maze_generation_algorithm</p>
<p>http://en.wikipedia.org/wiki/Maze</p>
<hr style="border-top:black solid 1px" />©2012 "<a href="http://dourok.info">DouO's Blog</a>". 请在遵守<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh">CC协议</a>的前提使用该文章。<br />]]></content:encoded>
			<wfw:commentRss>http://dourok.info/2011/07/14/maze_generation_algorithm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>悠哉悠哉，辗转反侧</title>
		<link>http://dourok.info/2011/06/05/%e6%82%a0%e5%93%89%e6%82%a0%e5%93%89%ef%bc%8c%e8%be%97%e8%bd%ac%e5%8f%8d%e4%be%a7/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25e6%2582%25a0%25e5%2593%2589%25e6%2582%25a0%25e5%2593%2589%25ef%25bc%258c%25e8%25be%2597%25e8%25bd%25ac%25e5%258f%258d%25e4%25be%25a7</link>
		<comments>http://dourok.info/2011/06/05/%e6%82%a0%e5%93%89%e6%82%a0%e5%93%89%ef%bc%8c%e8%be%97%e8%bd%ac%e5%8f%8d%e4%be%a7/#comments</comments>
		<pubDate>Sat, 04 Jun 2011 20:15:08 +0000</pubDate>
		<dc:creator>DouO</dc:creator>
				<category><![CDATA[Life]]></category>

		<guid isPermaLink="false">http://dourok.info/?p=532</guid>
		<description><![CDATA[昨天晚上，也就是敏感瓷那天，跟几个老同学跑出去犯罪了，其实应该算是只醉没饭… 喝了几杯酒，一点醉意也没，还很精神。回来还写两个多小时的代码，丝毫不困，只是烦。 …… 居然把博客当微博，真是太水了。 抱怨一下老鹰，真的是自动gzip，速度又不快，等了快10秒页面空白，突然咔噔一下，全部载入好了。本来是想躺在床上用手机上的，但android上等的我受不了，直接起床开电脑了。 有点睡意，立马上床。 于 2011 年 06 月 05 日 03:59:17 ©2012 "DouO's Blog". 请在遵守CC协议的前提使用该文章。]]></description>
			<content:encoded><![CDATA[<p>昨天晚上，也就是敏感瓷那天，跟几个老同学跑出去犯罪了，其实应该算是只醉没饭…<br />
喝了几杯酒，一点醉意也没，还很精神。回来还写两个多小时的代码，丝毫不困，只是烦。<br />
……<br />
居然把博客当微博，真是太水了。<br />
抱怨一下老鹰，真的是自动gzip，速度又不快，等了快10秒页面空白，突然咔噔一下，全部载入好了。本来是想躺在床上用手机上的，但android上等的我受不了，直接起床开电脑了。</p>
<p>有点睡意，立马上床。</p>
<p>于 2011 年 06 月 05 日 03:59:17</p>
<hr style="border-top:black solid 1px" />©2012 "<a href="http://dourok.info">DouO's Blog</a>". 请在遵守<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh">CC协议</a>的前提使用该文章。<br />]]></content:encoded>
			<wfw:commentRss>http://dourok.info/2011/06/05/%e6%82%a0%e5%93%89%e6%82%a0%e5%93%89%ef%bc%8c%e8%be%97%e8%bd%ac%e5%8f%8d%e4%be%a7/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>System.in的困惑</title>
		<link>http://dourok.info/2011/05/28/a_puzzle_of_system-in/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=a_puzzle_of_system-in</link>
		<comments>http://dourok.info/2011/05/28/a_puzzle_of_system-in/#comments</comments>
		<pubDate>Fri, 27 May 2011 19:54:33 +0000</pubDate>
		<dc:creator>DouO</dc:creator>
				<category><![CDATA[Coder]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[System.in]]></category>

		<guid isPermaLink="false">http://dourok.info/?p=519</guid>
		<description><![CDATA[先看下下面代码先 static class Thread1 extends Thread &#123; &#160; &#160; &#160; &#160; @Override &#160; &#160; &#160; &#160; public void run&#40;&#41; &#123; &#160; &#160; &#160; &#160; &#160; &#160; try &#123; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; InputStream in = System.in; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; OutputStream out = System.out; &#160; &#160; &#160; [...]]]></description>
			<content:encoded><![CDATA[<p>先看下下面代码先</p>
<div class="codecolorer-container java railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">class</span> Thread1 <span style="color: #000000; font-weight: bold;">extends</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Athread+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Thread</span></a> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; @Override<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> run<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Ainputstream+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">InputStream</span></a> in <span style="color: #339933;">=</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">in</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aoutputstream+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">OutputStream</span></a> out <span style="color: #339933;">=</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">out</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">int</span> i <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>i <span style="color: #339933;">=</span> in.<span style="color: #006633;">read</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; out.<span style="color: #006633;">write</span><span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aioexception+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">IOException</span></a> ex<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ex.<span style="color: #006633;">printStackTrace</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span></div></div>
<p>这段代码很正常，线程跑起来的结果和你想的一样，在终端上输入一行，按下回车就回显这一行，显然System.in是行缓冲的(linebuffered)，不是像getch那样输入一个就回显一个。在没有按下回车之前in.read()就一直阻塞。<br />
再来看下这一段代码<span id="more-519"></span></p>
<div class="codecolorer-container java railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">class</span> Thread2 <span style="color: #000000; font-weight: bold;">extends</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Athread+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Thread</span></a> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; @Override<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> run<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Ainputstream+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">InputStream</span></a> in <span style="color: #339933;">=</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">in</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aoutputstream+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">OutputStream</span></a> out <span style="color: #339933;">=</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">out</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">byte</span> buffer<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">10</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">int</span> i <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>i<span style="color: #339933;">=</span>in.<span style="color: #006633;">read</span><span style="color: #009900;">&#40;</span>buffer<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">!=-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; out.<span style="color: #006633;">write</span><span style="color: #009900;">&#40;</span>buffer, <span style="color: #cc66cc;">0</span>, i<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aioexception+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">IOException</span></a> ex<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ex.<span style="color: #006633;">printStackTrace</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span></div></div>
<p>Thread2跑起来结果跟Thread1一模一样，输入一行回显一行，但代码却有点区别，多了<code class="codecolorer java geshi"><span class="java"><span style="color: #000066; font-weight: bold;">byte</span> buffer<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">10</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></span></code>这是一个缓冲，读取的时候不是一次一个字节了，而是<code class="codecolorer java geshi"><span class="java">in.<span style="color: #006633;">read</span><span style="color: #009900;">&#40;</span>buffer<span style="color: #009900;">&#41;</span></span></code>，这个方法等同于<code class="codecolorer java geshi"><span class="java">in.<span style="color: #006633;">read</span><span style="color: #009900;">&#40;</span>buffer, <span style="color: #cc66cc;">0</span>, buffer.<span style="color: #006633;">length</span><span style="color: #009900;">&#41;</span></span></code>，也就是说要先把buffer读满，read方法才会结束。然后我困惑了，Thread2运行起来竟然Thread1一模一样。如果你输入abc然后回车，Thread2也会立刻回显abc\n。这时候的字节数只有4还没把buffer填满，但in.read(buffer)却返回了，我参考了文档对InputStream中read(byte[] b, int off, int len) 的说明：</p>
<blockquote><p>
&#8230;将输入流中最多 len 个数据字节读入字节数组。尝试读取多达 len 字节，但可能读取较少数量。以整数形式返回实际读取的字节数。<br />
在输入数据可用、检测到流的末尾或者抛出异常前，此方法一直阻塞。&#8230;</p></blockquote>
<p>前一句又“尝试”又”可能”的，太模糊暂时忽略，第二提出了不阻塞的情况，看似除了“输入数据可用”理解有点模糊外，其他都明显不符合，那理应阻塞的方法是什么原因让它提前返回呢？带着这个疑问，我看了下InputStream的源码，并在Thread3中实现了一个一模一样的方法（如文档所说的，就是反复调用read()）：</p>
<div class="codecolorer-container java railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">class</span> Thread3 <span style="color: #000000; font-weight: bold;">extends</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Athread+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Thread</span></a> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">int</span> read<span style="color: #009900;">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Ainputstream+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">InputStream</span></a> in, <span style="color: #000066; font-weight: bold;">byte</span> b<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span>, <span style="color: #000066; font-weight: bold;">int</span> off, <span style="color: #000066; font-weight: bold;">int</span> len<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aioexception+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">IOException</span></a> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>b <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Anullpointerexception+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">NullPointerException</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>off <span style="color: #339933;">&lt;</span> <span style="color: #cc66cc;">0</span> <span style="color: #339933;">||</span> len <span style="color: #339933;">&lt;</span> <span style="color: #cc66cc;">0</span> <span style="color: #339933;">||</span> len <span style="color: #339933;">&gt;</span> b.<span style="color: #006633;">length</span> <span style="color: #339933;">-</span> off<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aindexoutofboundsexception+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">IndexOutOfBoundsException</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>len <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">int</span> c<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;c<span style="color: #339933;">=</span> in.<span style="color: #006633;">read</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>c <span style="color: #339933;">==</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; b<span style="color: #009900;">&#91;</span>off<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span> c<span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">int</span> i <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> len<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; c <span style="color: #339933;">=</span> in.<span style="color: #006633;">read</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>c <span style="color: #339933;">==</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; b<span style="color: #009900;">&#91;</span>off <span style="color: #339933;">+</span> i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span> c<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aioexception+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">IOException</span></a> ee<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">return</span> i<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; @Override<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> run<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Ainputstream+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">InputStream</span></a> in <span style="color: #339933;">=</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">in</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aoutputstream+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">OutputStream</span></a> out <span style="color: #339933;">=</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">out</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">byte</span> buffer<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">10</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">int</span> i <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>i<span style="color: #339933;">=</span>read<span style="color: #009900;">&#40;</span>in,buffer,<span style="color: #cc66cc;">0</span>,buffer.<span style="color: #006633;">length</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">!=-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; out.<span style="color: #006633;">write</span><span style="color: #009900;">&#40;</span>buffer, <span style="color: #cc66cc;">0</span>, i<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aioexception+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">IOException</span></a> ex<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ex.<span style="color: #006633;">printStackTrace</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span></div></div>
<p>Thread3跑起来果然跟Thread2不一样，算是比较可理解了，不管你按下多少次回车，只有但buffer读满了，read(in,buffer,0,buffer.length)才会返回。当然这并不是说明System.in有什么问题，System.in必须是InputStream的子类，read(byte[] b, int off, int len) 被重载，必须的。我只是好奇它到底是怎么实现的，在Thread4我做了一些尝试：</p>
<div class="codecolorer-container java railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">class</span> Thread4 <span style="color: #000000; font-weight: bold;">extends</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Athread+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">Thread</span></a> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">int</span> read<span style="color: #009900;">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Ainputstream+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">InputStream</span></a> in, <span style="color: #000066; font-weight: bold;">byte</span> b<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span>, <span style="color: #000066; font-weight: bold;">int</span> off, <span style="color: #000066; font-weight: bold;">int</span> len<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aioexception+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">IOException</span></a> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>b <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Anullpointerexception+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">NullPointerException</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>off <span style="color: #339933;">&lt;</span> <span style="color: #cc66cc;">0</span> <span style="color: #339933;">||</span> len <span style="color: #339933;">&lt;</span> <span style="color: #cc66cc;">0</span> <span style="color: #339933;">||</span> len <span style="color: #339933;">&gt;</span> b.<span style="color: #006633;">length</span> <span style="color: #339933;">-</span> off<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aindexoutofboundsexception+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">IndexOutOfBoundsException</span></a><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>len <span style="color: #339933;">==</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">int</span> c<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;c<span style="color: #339933;">=</span> in.<span style="color: #006633;">read</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>c <span style="color: #339933;">==</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; b<span style="color: #009900;">&#91;</span>off<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span> c<span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">int</span> i <span style="color: #339933;">=</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> len<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>in.<span style="color: #006633;">available</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; c <span style="color: #339933;">=</span> in.<span style="color: #006633;">read</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>c <span style="color: #339933;">==</span> <span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; b<span style="color: #009900;">&#91;</span>off <span style="color: #339933;">+</span> i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#41;</span> c<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aioexception+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">IOException</span></a> ee<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">return</span> i<span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; @Override<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> run<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Ainputstream+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">InputStream</span></a> in <span style="color: #339933;">=</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">in</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aoutputstream+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">OutputStream</span></a> out <span style="color: #339933;">=</span> <a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Asystem+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">System</span></a>.<span style="color: #006633;">out</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">byte</span> buffer<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">10</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">int</span> i <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>i<span style="color: #339933;">=</span>read<span style="color: #009900;">&#40;</span>in,buffer,<span style="color: #cc66cc;">0</span>,buffer.<span style="color: #006633;">length</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">!=-</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; out.<span style="color: #006633;">write</span><span style="color: #009900;">&#40;</span>buffer, <span style="color: #cc66cc;">0</span>, i<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><a href="http://www.google.com/search?hl=en&amp;q=allinurl%3Aioexception+java.sun.com&amp;btnI=I%27m%20Feeling%20Lucky"><span style="color: #003399;">IOException</span></a> ex<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ex.<span style="color: #006633;">printStackTrace</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span></div></div>
<p>在in.available()永远有效且准确的前提下这个方法就跟System.in一样了，但我觉得这个前提很无力啊，但实际System.in它的实现是怎样的呢，还有为什么？</p>
<p>希望能在<a href="http://book.douban.com/subject/1230413/">深入理解计算机系统</a>找到答案，</p>
<p>最近看开始这本书，太棒了，才看第一章就对它入迷了，大学时代与它失之交臂真是遗憾啊。。。。啊。。。</p>
<hr style="border-top:black solid 1px" />©2012 "<a href="http://dourok.info">DouO's Blog</a>". 请在遵守<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh">CC协议</a>的前提使用该文章。<br />]]></content:encoded>
			<wfw:commentRss>http://dourok.info/2011/05/28/a_puzzle_of_system-in/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>更新了下CSS</title>
		<link>http://dourok.info/2011/05/24/%e6%9b%b4%e6%96%b0%e4%ba%86%e4%b8%8bcss/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=%25e6%259b%25b4%25e6%2596%25b0%25e4%25ba%2586%25e4%25b8%258bcss</link>
		<comments>http://dourok.info/2011/05/24/%e6%9b%b4%e6%96%b0%e4%ba%86%e4%b8%8bcss/#comments</comments>
		<pubDate>Tue, 24 May 2011 14:53:58 +0000</pubDate>
		<dc:creator>DouO</dc:creator>
				<category><![CDATA[Otaku]]></category>
		<category><![CDATA[Chrome]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[通用字体]]></category>

		<guid isPermaLink="false">http://dourok.info/?p=513</guid>
		<description><![CDATA[Ubuntu 下的Chrome 11默认字体很糟糕，不像Chromium 13，Chrome设置里只能改标准字体和等宽字体，经测试分别对应通用字体的fantasy(同未声明)和monospace。 无奈下添加了对文泉驿微米黑和微软雅黑的优先权。 详细整理于此：css通用字体 ©2012 "DouO's Blog". 请在遵守CC协议的前提使用该文章。]]></description>
			<content:encoded><![CDATA[<p>Ubuntu 下的Chrome 11默认字体很糟糕，不像Chromium 13，Chrome设置里只能改标准字体和等宽字体，经测试分别对应通用字体的fantasy(同未声明)和monospace。<br />
无奈下添加了对文泉驿微米黑和微软雅黑的优先权。<br />
详细整理于此：<a href="http://dourok.info/wiki/doku.php/%E7%BC%96%E7%A0%81/css/css%E9%80%9A%E7%94%A8%E5%AD%97%E4%BD%93">css通用字体</a></p>
<hr style="border-top:black solid 1px" />©2012 "<a href="http://dourok.info">DouO's Blog</a>". 请在遵守<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh">CC协议</a>的前提使用该文章。<br />]]></content:encoded>
			<wfw:commentRss>http://dourok.info/2011/05/24/%e6%9b%b4%e6%96%b0%e4%ba%86%e4%b8%8bcss/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>如何用Mercurial开始GoogleCode项目</title>
		<link>http://dourok.info/2011/05/11/managing-google-code-project-with-mercurial/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=managing-google-code-project-with-mercurial</link>
		<comments>http://dourok.info/2011/05/11/managing-google-code-project-with-mercurial/#comments</comments>
		<pubDate>Wed, 11 May 2011 10:15:30 +0000</pubDate>
		<dc:creator>DouO</dc:creator>
				<category><![CDATA[Otaku]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[Google Code]]></category>
		<category><![CDATA[hg]]></category>
		<category><![CDATA[Mercurial]]></category>

		<guid isPermaLink="false">http://dourok.info/?p=489</guid>
		<description><![CDATA[最近打算对自己乱糟糟的代码整理规划下，把一些项目提交到在线的代码仓库。因为自己还算是一个windows用户，所以还是放弃github，选择google code 加上看起来比较好用的Mercurial（CVS，GIT，Mercurial和SVN比较），Netbeans对Mercurial也有很好的支持。 Mercurial用起来还是很方便的，见Managing a Google Code project with Mercurial。下面的内容就是翻译整理自这文章，权当记录一下。 目录 1 安装Mercurial 2 设置默认用户 3 创建项目 4 不想每次提交都打地址？ 5 SVN转到Mercurial 安装Mercurial 首先，需要在你的机器上安装Mercurial，从这里http://mercurial.selenic.com/downloads/选择适合自己系统的版本下载安装。Ubuntu用户可以直接sudo apt-get install mercurial。搞定后，打开命令行窗口，键入hg version，如果出现类似下面信息的话就OK了。 分布式软件配置管理工具 - 水银 (版本 1.7.5) (see http://mercurial.selenic.com for more information) Copyright (C) 2005-2010 Matt Mackall and others This is free software; see the source for copying conditions. There [...]]]></description>
			<content:encoded><![CDATA[<p>最近打算对自己乱糟糟的代码整理规划下，把一些项目提交到在线的代码仓库。因为自己还算是一个windows用户，所以还是放弃github，选择google code 加上看起来比较好用的Mercurial（<a href="http://www.cnblogs.com/greenmile/archive/2010/04/20/VCS.html">CVS，GIT，Mercurial和SVN比较</a>），Netbeans对Mercurial也有很好的支持。</p>
<p>Mercurial用起来还是很方便的，见<a href="http://blog.dreasgrech.com/2010/07/managing-google-code-project-with.html">Managing a Google Code project with Mercurial</a>。下面的内容就是翻译整理自这文章，权当记录一下。</p>
<div id="toc_container" class="toc_wrap_right toc_black no_bullets">
<p class="toc_title">目录</p>
<ul class="toc_list">
<li><a href="#Mercurial">1 安装Mercurial</a></li>
<li><a href="#i">2 设置默认用户</a></li>
<li><a href="#i-2">3 创建项目</a></li>
<li><a href="#i-3">4 不想每次提交都打地址？</a></li>
<li><a href="#SVNMercurial">5 SVN转到Mercurial</a></li>
</ul>
</div>
<h3><span id="Mercurial">安装Mercurial</span></h3>
<p>首先，需要在你的机器上安装Mercurial，从这里http://mercurial.selenic.com/downloads/选择适合自己系统的版本下载安装。Ubuntu用户可以直接<code class="codecolorer text geshi"><span class="text">sudo apt-get install mercurial</span></code>。搞定后，打开命令行窗口，键入<code class="codecolorer text geshi"><span class="text">hg version</span></code>，如果出现类似下面信息的话就OK了。</p>
<blockquote><p><code class="codecolorer text geshi"><span class="text">分布式软件配置管理工具 - 水银 (版本 1.7.5)<br />
(see http://mercurial.selenic.com for more information)<br />
<br />
Copyright (C) 2005-2010 Matt Mackall and others<br />
This is free software; see the source for copying conditions. There is NO<br />
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.</span></code></p></blockquote>
<p>找不到命令的话请检查下环境变量。<br />
<span id="more-489"></span></p>
<h3><span id="i">设置默认用户</span></h3>
<p>当Mercurial成功安装后，还需要设置一个用户作为你提交到仓库的默认用户。<br />
windows用户的话，需要在用户目录（%USERPROFILE%）创建一个名为Mercurial.ini或者.hgrc的配置文件。比如创建<code class="codecolorer text geshi"><span class="text">C:\Users\Andreas\Mercurial.ini</span></code><br />
Linux在$HOME目录创建.hgrc文件<br />
然后在创建好的文件里加上下面内容</p>
<blockquote><p><code class="codecolorer text geshi"><span class="text">[ui]<br />
username = 你的名字 &lt;你的邮箱&gt;</span></code></p></blockquote>
<p>可以在<a href="http://www.selenic.com/mercurial/hgrc.5.html">这里</a>找到配置文件的更多选项。</p>
<h3><span id="i-2">创建项目</span></h3>
<p>点这个链接<a href="http://code.google.com/hosting/createProject">Google Project Hosting</a>创建新项目，记得在版本控制工具（Version control system）选项上选择Mercurial。填完其他项目后就可以创建自己的项目主页了。你的项目大概如：http://code.google.com/p/myhgproject/。<br />
接下来需要先建立本地仓库（repository），再把所有东西提交到在线仓库。首先，打开项目主页下的source标签页，或者这个地址http://code.google.com/p/myhgproject/source/checkout<br />
然后复制页面上的命令：<br />
<code class="codecolorer text geshi"><span class="text">hg clone https://myhgproject.googlecode.com/hg/ myhgproject</span></code><br />
在本地电脑上打开命令行窗口，进入到想要放着项目的文件夹如~/myproject，执行上面的命令。这个命令将会添加一个在线仓库的副本到本地机器上。这时应该在~/myproject下可以看到Mercurial创建的文件夹myhgproject。现在里面只有个.hg文件夹，接下来就可以把准备提交的项目文件复制到myhgproject下。</p>
<p>现在myhgproject文件夹下已经有项目需要的所有文件夹了，再接下来就要把这些文件添加到本地仓库中，命令行窗口进入myhgproject，执行hg add，如果有新文件的话就会看到一堆anding xxx的信息。hg add 命令的作用就是把新文件标记为要添加到下一次要提交的仓库中(新添加的文件状态就会由?变为a，可用hg status查看)，所以接下来就是把这些文件提交到本地仓库中，<br />
使用命令：<br />
<code class="codecolorer text geshi"><span class="text">hg commit -m “Initial commit”</span></code><br />
-m 后面的参数是指你这次提交的的一些信息。比如，现在是第一次添加，所以可以说明Initial commit来说明是第一次提交的意思。</p>
<p>注意，到现在本地的代码还未提交到在线仓库。接下来才是要把本地的代码提交到在线仓库，不过首先你要知道你的google为你生成的 googlecode.com密码.在项目的source页面下可以看到这个链接：<a href="http://code.google.com/hosting/settings">http://code.google.com/hosting/settings</a>。现在就可以使用你的google用户名和这个密码提交更改到在线仓库了。比如用户名是andreas，密码是AbCdEfGHiJ12。可以用这个命令提交：<br />
<code class="codecolorer text geshi"><span class="text">hg push https://andreas:AbCdEfGHiJ12@myhgproject.googlecode.com/hg/</span></code><br />
现在应该可以在在线仓库看到你项目的所有文件了。以后每次做更改后想要提交都需要先提交到本地仓库，用这个命令：<br />
<code class="codecolorer text geshi"><span class="text">hg commit -m &quot;这次提交的一些信息&quot;</span></code><br />
也可以不加-m这个参数。如果要添加新文件的话记得先 <code class="codecolorer text geshi"><span class="text">hg add</span></code><br />
然后就可以继续这个命令提交到在线仓库<br />
<code class="codecolorer text geshi"><span class="text">hg push https://andreas:AbCdEfGHiJ12@myhgproject.googlecode.com/hg/</span></code></p>
<h3><span id="i-3">不想每次提交都打地址？</span></h3>
<p>没问题，其实可以直接键入<br />
<code class="codecolorer text geshi"><span class="text">hg push</span></code><br />
不过服务器会要求你输入密码，输入上面的密码后才可以成功提交。如果连密码也不想输，也可以。<br />
打开项目文件夹了的.hg文件夹，可以看到里面有个hgrc文件，如果没有的话也可以自己创建。<br />
在里面加入你的密码</p>
<blockquote><p><code class="codecolorer text geshi"><span class="text">[paths]<br />
default = https://andreas:AbCdEfGHiJ12@myhgproject.googlecode.com/hg/</span></code></p></blockquote>
<p>明文保存的，要小心密码被泄露。</p>
<h3><span id="SVNMercurial">SVN转到Mercurial</span></h3>
<p>可以参考这里<a href="http://leeiio.me/googlecode-converting-svn-to-hg/">在Google Code上用 Mercurial 取代 Subversion 管理你的项目</a>，我也没细看。</p>
<p>知道hg就是汞Hg吧 <img src='http://dourok.info/wp-includes/images/smilies/icon_lol.gif' alt=':lol:' class='wp-smiley' />  </p>
<hr style="border-top:black solid 1px" />©2012 "<a href="http://dourok.info">DouO's Blog</a>". 请在遵守<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/deed.zh">CC协议</a>的前提使用该文章。<br />]]></content:encoded>
			<wfw:commentRss>http://dourok.info/2011/05/11/managing-google-code-project-with-mercurial/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

