<?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>Thu, 20 Sep 2012 17:28:10 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4.1</generator>
		<item>
		<title>可交互的 adb devices</title>
		<link>http://dourok.info/2012/06/26/selecting-adb-device/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=selecting-adb-device</link>
		<comments>http://dourok.info/2012/06/26/selecting-adb-device/#comments</comments>
		<pubDate>Mon, 25 Jun 2012 16:48:52 +0000</pubDate>
		<dc:creator>DouO</dc:creator>
				<category><![CDATA[Coder]]></category>
		<category><![CDATA[adb]]></category>
		<category><![CDATA[ADT]]></category>
		<category><![CDATA[Android]]></category>

		<guid isPermaLink="false">http://dourok.info/?p=854</guid>
		<description><![CDATA[$ adb hell 1&#41; HT18HTB00535 device 2&#41; HT04RL9010 [...]]]></description>
			<content:encoded><![CDATA[<div class="codecolorer-container bash railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ adb hell<br />
<span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> HT18HTB00535 device<br />
<span style="color: #000000;">2</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> HT04RL901008 device<br />
Select the device to use, <span style="color: #000000; font-weight: bold;">&lt;</span>q<span style="color: #000000; font-weight: bold;">&gt;</span> to quit: <span style="color: #000000;">1</span><br />
shell<span style="color: #000000; font-weight: bold;">@</span>android:<span style="color: #000000; font-weight: bold;">/</span> $</div></div>
<p></q></p>
<p>即便有了方便的 Eclipse+ADT ，偶尔在命令行下敲个 adb 也是少不了的。像我这样每天要切换操作系统的开发者，下面这个错误提示是每天都要遇到的：</p>
<blockquote><p>Re-installation failed due to different application signatures.<br />
You must perform a full uninstall of the application. WARNING: This will remove the application data!<br />
Please execute &#8216;adb uninstall your.package.namespace&#8217; in a shell.<a href="#e1"><sup>1)</sup></a></p></blockquote>
<p><span id="more-854"></span></p>
<p>如果你忘记了你已连接了多台设备就兴匆匆地敲入，</p>
<div class="codecolorer-container bash railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">adb uninstall your.package.namespace</div></div>
<p>那么下面这个错误也是不可避免的：</p>
<div class="codecolorer-container bash railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">error: <span style="color: #c20cb9; font-weight: bold;">more</span> than one device and emulator</div></div>
<p>这时候又得用</p>
<div class="codecolorer-container bash railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">adb devices</div></div>
<p>然后再选择，复制，粘帖打印出来的目标序列号，才能再执行。</p>
<div class="codecolorer-container bash railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">adb <span style="color: #660033;">-s</span> uninstall your.package.namespace</div></div>
<p>不过现在好了，<a href="http://dtmilano.blogspot.com/">dtmilano</a> 提供了一个可交互的adb，<a href="http://dtmilano.blogspot.com/2012/03/selecting-adb-device.html">原文见此。</a></p>
<p>这个交互的 adb 由两个脚本组成，第一个是<strong>android-select-device</strong>。用于提示用户选择设备。</p>
<div class="codecolorer-container bash railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666; font-style: italic;">#! /bin/bash</span><br />
<span style="color: #666666; font-style: italic;"># selects an android device</span><br />
<br />
<span style="color: #007800;">PROGNAME</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">basename</span> <span style="color: #007800;">$0</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
<span style="color: #007800;">UNAME</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">uname</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
<span style="color: #007800;">DEVICE_OPT</span>=<br />
<span style="color: #000000; font-weight: bold;">for</span> opt <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #ff0000;">&quot;$@&quot;</span><br />
<span style="color: #000000; font-weight: bold;">do</span><br />
<span style="color: #000000; font-weight: bold;">case</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$opt</span>&quot;</span> <span style="color: #000000; font-weight: bold;">in</span><br />
<span style="color: #660033;">-d</span><span style="color: #000000; font-weight: bold;">|</span>-e<span style="color: #000000; font-weight: bold;">|</span>-s<span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
<span style="color: #007800;">DEVICE_OPT</span>=<span style="color: #007800;">$opt</span><br />
<span style="color: #000000; font-weight: bold;">;;</span><br />
<span style="color: #000000; font-weight: bold;">esac</span><br />
<span style="color: #000000; font-weight: bold;">done</span><br />
<span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-n</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$DEVICE_OPT</span>&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #000000; font-weight: bold;">&amp;</span>amp;<span style="color: #000000; font-weight: bold;">&amp;</span>amp; <span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">0</span><br />
<span style="color: #007800;">DEV</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span>adb devices <span style="color: #000000;">2</span><span style="color: #000000; font-weight: bold;">&amp;</span>gt;<span style="color: #000000; font-weight: bold;">&amp;</span>amp;<span style="color: #000000;">1</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">tail</span> <span style="color: #660033;">-n</span> +<span style="color: #000000;">2</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sed</span> <span style="color: #ff0000;">'/^$/d'</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-z</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$DEV</span>&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span><br />
<span style="color: #000000; font-weight: bold;">then</span><br />
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$PROGNAME</span>: ERROR: There's no connected devices.&quot;</span> <span style="color: #000000; font-weight: bold;">&amp;</span>gt;<span style="color: #000000; font-weight: bold;">&amp;</span>amp;<span style="color: #000000;">2</span><br />
<span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">1</span><br />
<span style="color: #000000; font-weight: bold;">fi</span><br />
<span style="color: #007800;">N</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$DEV</span>&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">wc</span> <span style="color: #660033;">-l</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sed</span> <span style="color: #ff0000;">'s/ //g'</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">case</span> <span style="color: #007800;">$N</span> <span style="color: #000000; font-weight: bold;">in</span><br />
<span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
<span style="color: #666666; font-style: italic;"># only one device detected</span><br />
<span style="color: #007800;">D</span>=<span style="color: #007800;">$DEV</span><br />
<span style="color: #000000; font-weight: bold;">;;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">*</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
<span style="color: #666666; font-style: italic;"># more than one device detected</span><br />
<span style="color: #007800;">OLDIFS</span>=<span style="color: #007800;">$IFS</span><br />
<span style="color: #007800;">IFS</span>=<span style="color: #ff0000;">&quot;<br />
&quot;</span><br />
<span style="color: #007800;">PS3</span>=<span style="color: #ff0000;">&quot;Select the device to use, &lt;q&gt; to quit: &quot;</span><br />
<span style="color: #000000; font-weight: bold;">select</span> D <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #007800;">$DEV</span><br />
<span style="color: #000000; font-weight: bold;">do</span><br />
<span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$REPLY</span>&quot;</span> = <span style="color: #ff0000;">'q'</span> <span style="color: #660033;">-o</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$REPLY</span>&quot;</span> = <span style="color: #ff0000;">'Q'</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #000000; font-weight: bold;">&amp;</span>amp;<span style="color: #000000; font-weight: bold;">&amp;</span>amp; <span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">2</span><br />
<span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-n</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$D</span>&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #000000; font-weight: bold;">&amp;</span>amp;<span style="color: #000000; font-weight: bold;">&amp;</span>amp; <span style="color: #7a0874; font-weight: bold;">break</span><br />
<span style="color: #000000; font-weight: bold;">done</span><span style="color: #000000; font-weight: bold;">&lt;/</span>q<span style="color: #000000; font-weight: bold;">&gt;</span><br />
<br />
<span style="color: #007800;">IFS</span>=<span style="color: #007800;">$OLDIFS</span><br />
<span style="color: #000000; font-weight: bold;">;;</span><br />
<span style="color: #000000; font-weight: bold;">esac</span><br />
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-z</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$D</span>&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span><br />
<span style="color: #000000; font-weight: bold;">then</span><br />
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$PROGNAME</span>: ERROR: target device coulnd't be determined&quot;</span> <span style="color: #000000; font-weight: bold;">&amp;</span>gt;<span style="color: #000000; font-weight: bold;">&amp;</span>amp;<span style="color: #000000;">2</span><br />
<span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">1</span><br />
<span style="color: #000000; font-weight: bold;">fi</span><br />
<br />
<span style="color: #666666; font-style: italic;"># this didn't work on Darwin</span><br />
<span style="color: #666666; font-style: italic;"># echo &quot;-s ${D%% *}&quot;</span><br />
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;-s <span style="color: #007800;">$(echo ${D} | sed 's/ .*$//')</span>&quot;</span></div></div>
<p>把上面代码复制保存到 <strong>android-select-device</strong> 这个文件里。第二个文件是<strong>my-adb</strong>，它是用来代替原本的adb的。当adb devices 多于一个的时候就会调用 <strong>android-select-device</strong> 让用户选择设备。</p>
<div class="codecolorer-container bash railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666; font-style: italic;">#! /bin/bash</span><br />
<span style="color: #666666; font-style: italic;"># This command can be used as an alias for adb and it will prompt for the</span><br />
<span style="color: #666666; font-style: italic;"># device selection if needed</span><br />
<span style="color: #666666; font-style: italic;"># alias adb=my-adb</span><br />
<br />
<span style="color: #000000; font-weight: bold;">set</span> +x<br />
<span style="color: #007800;">PROGNAME</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">basename</span> <span style="color: #007800;">$0</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
<span style="color: #007800;">ADB</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">which</span> adb<span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #660033;">-z</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$ADB</span>&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span><br />
<span style="color: #000000; font-weight: bold;">then</span><br />
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$PROGNAME</span>: ERROR: cannot found adb&quot;</span><br />
<span style="color: #7a0874; font-weight: bold;">exit</span> <span style="color: #000000;">1</span><br />
<span style="color: #000000; font-weight: bold;">fi</span><br />
<br />
<span style="color: #000000; font-weight: bold;">set</span> <span style="color: #660033;">-e</span><br />
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$#</span> == <span style="color: #000000;">0</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span><br />
<span style="color: #000000; font-weight: bold;">then</span><br />
<span style="color: #666666; font-style: italic;"># no arguments</span><br />
<span style="color: #7a0874; font-weight: bold;">exec</span> <span style="color: #007800;">$ADB</span><br />
<span style="color: #000000; font-weight: bold;">elif</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #ff0000;">&quot;$1&quot;</span> == <span style="color: #ff0000;">'devices'</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span><br />
<span style="color: #000000; font-weight: bold;">then</span><br />
<span style="color: #666666; font-style: italic;"># adb devices should not accept -s, -e or -d</span><br />
<span style="color: #7a0874; font-weight: bold;">exec</span> <span style="color: #007800;">$ADB</span> devices<br />
<span style="color: #000000; font-weight: bold;">else</span><br />
<span style="color: #666666; font-style: italic;"># because of the set -e, if selecting the device fails it exits</span><br />
<span style="color: #007800;">S</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span>android-select-device <span style="color: #ff0000;">&quot;$@&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><br />
<span style="color: #7a0874; font-weight: bold;">exec</span> <span style="color: #007800;">$ADB</span> <span style="color: #007800;">$S</span> <span style="color: #ff0000;">&quot;$@&quot;</span><br />
<span style="color: #000000; font-weight: bold;">fi</span></div></div>
<p>同样的把上面代码复制保存到文件 <strong>my-adb</strong> 。<br />
接下来把这两个脚本加入到 $PATH 里面。我的做法是在 $ANDROID_SDK_HOME 里面建个 my-tools 文件夹，再把脚本放进去。然后直接在 $PATH 里添加这个目录</p>
<div class="codecolorer-container bash railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">PATH</span>=<span style="color: #007800;">$PATH</span>:<span style="color: #007800;">$ANDROID_SDK_HOME</span><span style="color: #000000; font-weight: bold;">/</span>my-tools</div></div>
<p>最后给 my-adb 加个 adb 别名，让它替换掉原来的 adb。</p>
<div class="codecolorer-container bash railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #7a0874; font-weight: bold;">alias</span> <span style="color: #007800;">adb</span>=my-adb</div></div>
<p>确保环境变量生效后，就可以键入 adb 试试看了。如果运行失败，确保两个脚本的权限为可执行，如 744 。</p>
<p>运行 adb hell 后，如果有多个设备的话，你应该可以看到文章一开始的输出：</p>
<div class="codecolorer-container bash railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">$ adb hell<br />
<span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> HT18HTB00535 device<br />
<span style="color: #000000;">2</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> HT04RL901008 device<br />
Select the device to use, <span style="color: #000000; font-weight: bold;">&lt;</span>q<span style="color: #000000; font-weight: bold;">&gt;</span> to quit: <span style="color: #000000;">1</span><br />
shell<span style="color: #000000; font-weight: bold;">@</span>android:<span style="color: #000000; font-weight: bold;">/</span> $</div></div>
<p></q></p>
<p>不过这个脚本也是有缺陷的，不管 adb 的子命令需不需要指定device，只要多于一个设备连接着，它都会提示选择设备。</p>
<h3 name="e1">注解</h3>
<p> <a name="e1">1)</a> 这个问题是由于不同的机器使用不同的<strong>debug.keystore</strong>，导致安装的时候验证错误。所有开发的机器使用相同的<strong>debug.keystore</strong>便可以避免这个问题再次发生。在 Eclipse 下 Window -> Preferences -> Android -> Build -> Custom debug keystore 中可以更改。</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/06/26/selecting-adb-device/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>LightsOut 解法小探</title>
		<link>http://dourok.info/2012/05/31/lights-out-solution/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=lights-out-solution</link>
		<comments>http://dourok.info/2012/05/31/lights-out-solution/#comments</comments>
		<pubDate>Thu, 31 May 2012 14:20:09 +0000</pubDate>
		<dc:creator>DouO</dc:creator>
				<category><![CDATA[Coder]]></category>
		<category><![CDATA[LightsOut]]></category>
		<category><![CDATA[游戏]]></category>
		<category><![CDATA[算法]]></category>
		<category><![CDATA[线性代数]]></category>

		<guid isPermaLink="false">http://dourok.info/?p=778</guid>
		<description><![CDATA[Lights Out(关灯游戏) 是一款经典的老游戏，维基百科上说Lights Out 是在1995年由 Ti [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://dourok.info/wp-content/uploads/2012/05/light_out_banner.png"><img class="alignnone size-full wp-image-818" title="light_out_banner" src="http://dourok.info/wp-content/uploads/2012/05/light_out_banner.png" alt="" width="706" height="282" /></a></p>
<p>Lights Out(关灯游戏) 是一款经典的老游戏，维基百科上说Lights Out 是在1995年由 <a title="Tiger Toys" href="https://en.wikipedia.org/wiki/Tiger_Toys">Tiger Toys</a> 第一次发行。接触它却在去年的时候Gnome3的小游戏里。Lights Out 的规则很简单，游戏由一个 5 * 5 格的棋盘构成，每格子都是一颗灯，灯肯定是有两种状态，亮或者暗。游戏一开始棋盘上会亮起一些灯，你的目标就是把所有亮起灯都关掉，亮起的灯点一下就会关掉，但游戏当然不会这么简单，点一下灯的时候还会有一些附加影响，准确的说就是点一下灯的时候会切换它和四周也就是是上下左右的灯的状态。找到了一个在线的Lights Out，<a href="http://www.addictinggames.com/puzzle-games/lightsout.jsp">http://www.addictinggames.com/puzzle-games/lightsout.jsp</a>。一般能过第五关就差不多了吧。</p>
<p><span id="more-778"></span></p>
<p>不过即便是第一关，如果一开始摸不到基本的门道，乱点的话基本上想点回来是很难的，为什么？<span class='MathJax_Preview'><img src='http://dourok.info/wp-content/plugins/latex/cache/tex_6f9b0569a1a71c0692755f6b3520c622.gif' style='vertical-align: middle; border: none; ' class='tex' alt="2^{25}" /></span><script type='math/tex'>2^{25}</script>等于多少 ，作为一个合格的码农应该脱口而出，33554432 ！好吧我承认我也是用计算器的。要玩这游戏首先要明白一个道理：你关的不是灯，是寂寞…噢不，是开关！先不管棋盘上的灯光状态如何，也不管一个开关可以控制多少颗灯，只要知道你点一下方块，就等于切换一次开关，开关就从状态1转换到状态0，再点一下方块，开关又从状态0切换回状态1。这里的0和1也就是开关开和关两种状态，明白这一点很重要，把所有开着的开关都关闭就是完成游戏，所有开着的开关都关闭，肯定没有灯是亮的是吧，但是反过来并不一定成立哦，后面会说到这个。它还可以继续往下推，第一点，<strong>每一个方块只有点第一下才是有意义的</strong>，点第二下也就切换会原始状态，点N下也就是来来回回切换而已。第二点，<strong>开关关闭的顺序无关紧要</strong>。从上往下点，从下往上点都没关系。</p>
<p>如果你有迈克那么牛逼的话，相信现在已经能够透过亮着灯光看到后面隐藏的开关了吧，看不到也没关系先想象一下。我们知道一个开关控制着上下左右和本身的灯光，相对的，<strong>一颗灯亮与否，取决于它本身和四周开关的状态，当有奇数个开关开着的时候，灯就亮，偶数个的时候灯就是暗着的</strong>。再看看第一行，第一行上的一颗灯，能影响到它的开关有本身、左右，这三个都是第一 行上的开关，另外还有下方位于第二行的开关，而上方的开关因为是第一行所以是不存在的。现在假设一下，第一行所有开关都被关闭了，那么此时第一行如果还有亮着的灯，能控制这些灯的开关就只剩下第二行的开关，一颗亮着的灯，显然第二行其对着的开关肯定是打开的，相反的，第一行的灯是暗的，那么第二行对应的开关肯定是关闭的，这样第二行打开的开关就是其上面的灯还亮着的那些。照着第一行亮着的灯把第二行的开关全部关掉，现在一行的灯应该是全暗的，第二行的开关也全部关闭了，第二行还亮着的灯也就只有第三开关能影响到了。同样的，此时第二、三行的情况就跟前面第一、二行的情形一样了。以此类推，第三、四、五行的开关都可以这样关掉，此时游戏也就解决了。终于有一条有用的结论了，<strong>当第一行的开关全部关闭后，其他行的开关通过一个唯一且固定的模式来把开关全部关闭，也就是说对应着上一行亮着的灯把下一行对应的开关关闭就行。</strong>有了这个结论，现在已经把游戏的难度降低不少了，我们只要猜对第一行打开的开关就可以把游戏K.O.了。这个结论，我们把问题猜测的规模从<span class='MathJax_Preview'><img src='http://dourok.info/wp-content/plugins/latex/cache/tex_d4636ba74d3371284cc4b62c20c2ca0d.gif' style='vertical-align: middle; border: none; ' class='tex' alt="2^{25}=33554432" /></span><script type='math/tex'>2^{25}=33554432</script>降到<span class='MathJax_Preview'><img src='http://dourok.info/wp-content/plugins/latex/cache/tex_7febadb9fe60625acda056d7b002498d.gif' style='vertical-align: middle; border: none; ' class='tex' alt="2^5=32 " /></span><script type='math/tex'>2^5=32 </script>。当然这样有点无趣，也不会变得完全没有难度。 但对于计算机来说，那确实是易过吃碗水，遍历第一行的所有可能性，再校验是不是一个解。</p>
<p>但是这种方法不能脱离暴力搜索，始终有点丑陋。我在看Gnome Lights Out 的源码的时候，发现了一篇论文讨论了如何用线性代数的方法来解决这个问题。非常简单的一个方法。</p>
<p>首先我们随便找一个开局状态，1表示灯是亮的，0表示灯是暗的。如下所示，</p>
<p><a href="http://dourok.info/wp-content/uploads/2012/05/light_out_state_1.png"><img class="alignnone size-full wp-image-821" title="light_out_state_1" src="http://dourok.info/wp-content/uploads/2012/05/light_out_state_1.png" alt="" width="353" height="282" /></a></p>
<p><span class='MathJax_Preview'><img src='http://dourok.info/wp-content/plugins/latex/cache/tex_22a88cc2cc03d040a35a5c2a6ec61a6e.gif' style='vertical-align: middle; border: none; ' class='tex' alt="\begin{vmatrix}1 & 0 & 0 & 0 & 0 \\1 & 1 & 1 & 1 & 0 \\1 & 1 & 1 & 1 & 1 \\1 & 1 & 1 & 1 & 0 \\1 & 0 & 0 & 0 & 0\\\end{vmatrix}" /></span><script type='math/tex'>\begin{vmatrix}1 & 0 & 0 & 0 & 0 \\1 & 1 & 1 & 1 & 0 \\1 & 1 & 1 & 1 & 1 \\1 & 1 & 1 & 1 & 0 \\1 & 0 & 0 & 0 & 0\\\end{vmatrix}</script></p>
<p>把这些数字放到一列里并标上号，就成了向量<span class='MathJax_Preview'><img src='http://dourok.info/wp-content/plugins/latex/cache/tex_9b37557c9ef520391320170e7651f088.gif' style='vertical-align: middle; border: none; ' class='tex' alt="\vec b=(b_{1,1},b_{1,2},\cdots,b_{1,5},b_{2,1},\cdots,b_{5,5})^T" /></span><script type='math/tex'>\vec b=(b_{1,1},b_{1,2},\cdots,b_{1,5},b_{2,1},\cdots,b_{5,5})^T</script></p>
<p>当我们按一下开关，<span class='MathJax_Preview'><img src='http://dourok.info/wp-content/plugins/latex/cache/tex_fcdd61484b31af8082ca2030cea8f4f6.gif' style='vertical-align: middle; border: none; ' class='tex' alt="\vec b" /></span><script type='math/tex'>\vec b</script>又会发生什么变化呢？比如按下位于坐标(1,1)的开关，记为<span class='MathJax_Preview'><img src='http://dourok.info/wp-content/plugins/latex/cache/tex_37958543e1edaf9fdcd19758cf49942c.gif' style='vertical-align: middle; border: none; ' class='tex' alt="s_{1,1}" /></span><script type='math/tex'>s_{1,1}</script>。当<span class='MathJax_Preview'><img src='http://dourok.info/wp-content/plugins/latex/cache/tex_37958543e1edaf9fdcd19758cf49942c.gif' style='vertical-align: middle; border: none; ' class='tex' alt="s_{1,1}" /></span><script type='math/tex'>s_{1,1}</script>按下时，他会改变<span class='MathJax_Preview'><img src='http://dourok.info/wp-content/plugins/latex/cache/tex_f958f58bde88b83259a2f31e770684ed.gif' style='vertical-align: middle; border: none; ' class='tex' alt="b_{1,1} ,b_{1,2},b_{2,1}" /></span><script type='math/tex'>b_{1,1} ,b_{1,2},b_{2,1}</script>的状态，如果灯光原来的状态为0，那么就变成1，原来为1就变成0。这个刚好是GF(2)上的加法，GF(2)怎么说呢，其实和一般的数域没什么区别，因为只有两个元素 0， 1 。那么在这个域上 1 + 1 就等于 0 。我们把<span class='MathJax_Preview'><img src='http://dourok.info/wp-content/plugins/latex/cache/tex_37958543e1edaf9fdcd19758cf49942c.gif' style='vertical-align: middle; border: none; ' class='tex' alt="s_{1,1}" /></span><script type='math/tex'>s_{1,1}</script>也用向量表示，它就是这个样子的</p>
<p><span class='MathJax_Preview'><img src='http://dourok.info/wp-content/plugins/latex/cache/tex_8078d19d78cb6e81fcd3bc5c4819a4d1.gif' style='vertical-align: middle; border: none; ' class='tex' alt="\vec s_{1,1}=(1,1,0,0,0,1,0,\cdots,0)" /></span><script type='math/tex'>\vec s_{1,1}=(1,1,0,0,0,1,0,\cdots,0)</script></p>
<p>当我们在游戏中点一下开关<span class='MathJax_Preview'><img src='http://dourok.info/wp-content/plugins/latex/cache/tex_37958543e1edaf9fdcd19758cf49942c.gif' style='vertical-align: middle; border: none; ' class='tex' alt="s_{1,1}" /></span><script type='math/tex'>s_{1,1}</script>，数学上就等于<span class='MathJax_Preview'><img src='http://dourok.info/wp-content/plugins/latex/cache/tex_3f16be9bab07181a722d3e2a5c3a0c25.gif' style='vertical-align: middle; border: none; ' class='tex' alt="\vec b + \vec s_{1,1}" /></span><script type='math/tex'>\vec b + \vec s_{1,1}</script> 。我们还可以继续表示其他开关的向量，比如，</p>
<p><span class='MathJax_Preview'><img src='http://dourok.info/wp-content/plugins/latex/cache/tex_f95c6ab90b1ab553fd4063ef7eb0a1d5.gif' style='vertical-align: middle; border: none; ' class='tex' alt="\vec s_{1,2}=(1,1,1,0,0,0,1,\cdots,0)" /></span><script type='math/tex'>\vec s_{1,2}=(1,1,1,0,0,0,1,\cdots,0)</script></p>
<p><span class='MathJax_Preview'><img src='http://dourok.info/wp-content/plugins/latex/cache/tex_062575b8281f9abd15767e0d93a594e1.gif' style='vertical-align: middle; border: none; ' class='tex' alt="\vec s_{5,5}=(0,\cdots,0,1,0,0,0,1,1)" /></span><script type='math/tex'>\vec s_{5,5}=(0,\cdots,0,1,0,0,0,1,1)</script> 。</p>
<p>前面我们说过，这个游戏的目的就是把全部打开着的开关都关闭了，开关的状态我们已经用<span class='MathJax_Preview'><img src='http://dourok.info/wp-content/plugins/latex/cache/tex_47848ab772afc2635c3f3f6b607ae7c2.gif' style='vertical-align: middle; border: none; ' class='tex' alt=" s_{1,1},\cdots,s_{5,5}" /></span><script type='math/tex'> s_{1,1},\cdots,s_{5,5}</script> 表示，不多不少刚好25个，如果我们用1来表示这个开关是打开，0来表示关闭，那么一个游戏初始的开关状态也可以用一个向量来表示，<br />
<span class='MathJax_Preview'><img src='http://dourok.info/wp-content/plugins/latex/cache/tex_70a9a476ef0b6fcbc0dddbcbbb085058.gif' style='vertical-align: middle; border: none; ' class='tex' alt="\vec x=(x_{1,1},x_{1,2},\cdots,x_{1,5},x_{2,1},\cdots,x_{5,5})^T" /></span><script type='math/tex'>\vec x=(x_{1,1},x_{1,2},\cdots,x_{1,5},x_{2,1},\cdots,x_{5,5})^T</script>。由于游戏的开关状态时未知的，是我们玩这个游戏的目的，所以这里用x表示。<span class='MathJax_Preview'><img src='http://dourok.info/wp-content/plugins/latex/cache/tex_8bb50605ff63759107f02187b2ee1a8d.gif' style='vertical-align: middle; border: none; padding-bottom:1px;' class='tex' alt="\vec x" /></span><script type='math/tex'>\vec x</script>即是初始局面打开的开关，也是灯全暗变换到棋盘初始状态所需要点开的开关，所以我们也把<span class='MathJax_Preview'><img src='http://dourok.info/wp-content/plugins/latex/cache/tex_8bb50605ff63759107f02187b2ee1a8d.gif' style='vertical-align: middle; border: none; padding-bottom:1px;' class='tex' alt="\vec x" /></span><script type='math/tex'>\vec x</script>称为一个策略。<span class='MathJax_Preview'><img src='http://dourok.info/wp-content/plugins/latex/cache/tex_fcdd61484b31af8082ca2030cea8f4f6.gif' style='vertical-align: middle; border: none; ' class='tex' alt="\vec b" /></span><script type='math/tex'>\vec b</script>表示初始状态，<span class='MathJax_Preview'><img src='http://dourok.info/wp-content/plugins/latex/cache/tex_22401af2f8bf7292975ee6148950d519.gif' style='vertical-align: middle; border: none; ' class='tex' alt="\underline{0}" /></span><script type='math/tex'>\underline{0}</script>灯光全暗的状态。<br />
<span class='MathJax_Preview'><img src='http://dourok.info/wp-content/plugins/latex/cache/tex_fc55b4a5a0763e035cbe8729eeae17a9.gif' style='vertical-align: middle; border: none; ' class='tex' alt="\vec b =\underline{0}+x_{1,1}\vec s_{1,1}+\cdots+x_{1,5}\vec s_{1,5}+x_{2,1}\vec s_{2,1}+\cdots+x_{5,5}\vec s_{5,5}" /></span><script type='math/tex'>\vec b =\underline{0}+x_{1,1}\vec s_{1,1}+\cdots+x_{1,5}\vec s_{1,5}+x_{2,1}\vec s_{2,1}+\cdots+x_{5,5}\vec s_{5,5}</script></p>
<p>解上面的方程可以用下面这个线性方程来表示：<span class='MathJax_Preview'><img src='http://dourok.info/wp-content/plugins/latex/cache/tex_3bbce3bb8509bec3399f110b487b6228.gif' style='vertical-align: middle; border: none; ' class='tex' alt="A\vec x=\vec b" /></span><script type='math/tex'>A\vec x=\vec b</script><br />
其中A是一个 25 * 25 的矩阵：</p>
<p><span class='MathJax_Preview'><img src='http://dourok.info/wp-content/plugins/latex/cache/tex_2b043c9bb1514f04e5f2f5bee5ab5fed.gif' style='vertical-align: middle; border: none; ' class='tex' alt="A = \begin{vmatrix}B & I & O & O & O \\I & B & I & O & O \\O & I & B & I & O \\O & O & I & B & I \\O & O & O & I & B \\\end{vmatrix}" /></span><script type='math/tex'>A = \begin{vmatrix}B & I & O & O & O \\I & B & I & O & O \\O & I & B & I & O \\O & O & I & B & I \\O & O & O & I & B \\\end{vmatrix}</script></p>
<p>I是一个 5 * 5 的单位矩阵，O是一个 5 * 5 其元全部为零的矩阵。而B是这样一个矩阵：</p>
<p><span class='MathJax_Preview'><img src='http://dourok.info/wp-content/plugins/latex/cache/tex_358b34d1fcbc07348abec3717f3c1323.gif' style='vertical-align: middle; border: none; ' class='tex' alt="B = \begin{vmatrix}1 & 1 & 0 & 0 & 0 \\1 & 1 & 1 & 0 & 0 \\0 & 1 & 1 & 1 & 0 \\0 & 0 & 1 & 1 & 1 \\0 & 0 & 0 & 1 & 1 \\\end{vmatrix}" /></span><script type='math/tex'>B = \begin{vmatrix}1 & 1 & 0 & 0 & 0 \\1 & 1 & 1 & 0 & 0 \\0 & 1 & 1 & 1 & 0 \\0 & 0 & 1 & 1 & 1 \\0 & 0 & 0 & 1 & 1 \\\end{vmatrix}</script></p>
<p>如果把 I, O, B 代入 A 那么 A 的每一列都对应着一个开关的s向量。</p>
<p>采用高斯-若爾當消元法对A的增广矩阵<span class='MathJax_Preview'><img src='http://dourok.info/wp-content/plugins/latex/cache/tex_3bb6fb493b465bb8ab9903fa99283091.gif' style='vertical-align: middle; border: none; ' class='tex' alt="(A   \vec b)" /></span><script type='math/tex'>(A   \vec b)</script>，就可以求出<span class='MathJax_Preview'><img src='http://dourok.info/wp-content/plugins/latex/cache/tex_8bb50605ff63759107f02187b2ee1a8d.gif' style='vertical-align: middle; border: none; padding-bottom:1px;' class='tex' alt="\vec x" /></span><script type='math/tex'>\vec x</script> 。</p>
<p>如果令 <span class='MathJax_Preview'><img src='http://dourok.info/wp-content/plugins/latex/cache/tex_8aa13bc2c49445c2ffa02cdb58046cf7.gif' style='vertical-align: middle; border: none; ' class='tex' alt="\vec b = \bf{0}" /></span><script type='math/tex'>\vec b = \bf{0}</script>，在 5 * 5 的游戏规模下，解<span class='MathJax_Preview'><img src='http://dourok.info/wp-content/plugins/latex/cache/tex_077c1ae263f44e5dfbb288eb708d6f1e.gif' style='vertical-align: middle; border: none; ' class='tex' alt="A\vec x=\bf{0}" /></span><script type='math/tex'>A\vec x=\bf{0}</script>。除了 <span class='MathJax_Preview'><img src='http://dourok.info/wp-content/plugins/latex/cache/tex_c45962a691bcda8abfd50784ad493f90.gif' style='vertical-align: middle; border: none; padding-bottom:1px;' class='tex' alt="\vec x = \bf{0}" /></span><script type='math/tex'>\vec x = \bf{0}</script>外，还有另外两个解，分别是：</p>
<p><span class='MathJax_Preview'><img src='http://dourok.info/wp-content/plugins/latex/cache/tex_0f46a86d53d9e4f0dda715a901511b13.gif' style='vertical-align: middle; border: none; ' class='tex' alt="\vec x_{1}=(0,1,1,1,0,1,0,1,0,1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,0)^T" /></span><script type='math/tex'>\vec x_{1}=(0,1,1,1,0,1,0,1,0,1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,0)^T</script></p>
<p><span class='MathJax_Preview'><img src='http://dourok.info/wp-content/plugins/latex/cache/tex_e5af2990de26e20c2a86dd785532e7f4.gif' style='vertical-align: middle; border: none; ' class='tex' alt="\vec x_{2}=(1,0,1,0,1,1,0,1,0,1,0,0,0,0,0,1,0,1,0,1,1,0,1,0,1)^T" /></span><script type='math/tex'>\vec x_{2}=(1,0,1,0,1,1,0,1,0,1,0,0,0,0,0,1,0,1,0,1,1,0,1,0,1)^T</script></p>
<p>由此可见，5 * 5 游戏的解并不是唯一的，即便是灯光全暗，也不一定表示开关全部被关闭。另外，并不是所有可能性都有解。好了就先到这里，了解更多请见下面的链接：</p>
<ul>
<li><a href="http://git.gnome.org/browse/gnome-games/tree/lightsoff">gnome game lightsout的源码</a></li>
<li><a href="www.math.ksu.edu/~dmaldona/math551/lights_out.pdf">Turning Lights Out with Linear Algebra</a></li>
<li><a href="http://mathworld.wolfram.com/LightsOutPuzzle.html">mathworld 上的一个讨论</a></li>
<li><a href="http://www.cnblogs.com/pegasus/archive/2011/07/31/2123195.html">高斯-若尔当消元法的算法</a></li>
</ul>
<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/05/31/lights-out-solution/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<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 [...]]]></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>5</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[路边的野花独自开得这般灿烂，可曾有人为你驻足? 可野花从不管有没有人欣赏都照样开放。 从不向人类乞求一分一毫， [...]]]></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前上来吐槽下，记录下对博客做的修改和一些新理解。 首先取消了分类目录，全部通过标签来做归类 [...]]]></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>1</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.ja [...]]]></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可能会导致&#8221;Attach Sources&#8221;按钮失效。我试过了确实会这样（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 可以说我理想中的歌曲下载插件，主要是它可 [...]]]></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 class='MathJax_Preview'><img src='http://dourok.info/wp-content/plugins/latex/cache/tex_0f605e9d909d193d66f0de973517476d.gif' style='vertical-align: middle; border: none; ' class='tex' alt="</span>.*?<span style="color: #000099; font-weight: bold;">" /></span><script type='math/tex'></span>.*?<span style="color: #000099; font-weight: bold;"></script></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>8</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[迷宫,大家都在知道是什么吧.一种标准的迷宫可以是像下图这样的结构, 一个矩形空间上,布置出错综复杂的墙,本文讨 [...]]]></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>&#8220;迷宫设计不仅是线条和图案的组合，要有娱乐性、装饰性，还要考虑那些穿越迷宫者的感受，那样才趣味无穷&#8221;</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/one_of_spams/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=one_of_spams</link>
		<comments>http://dourok.info/2011/06/05/one_of_spams/#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[昨天晚上，也就是敏感瓷那天，跟几个老同学跑出去犯罪了，其实应该算是只醉没饭… 喝了几杯酒，一点醉意也没，还很精 [...]]]></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/one_of_spams/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; &#038;nb [...]]]></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>前一句又“尝试&#8221;又&#8221;可能&#8221;的，太模糊暂时忽略，第二提出了不阻塞的情况，看似除了“输入数据可用”理解有点模糊外，其他都明显不符合，那理应阻塞的方法是什么原因让它提前返回呢？带着这个疑问，我看了下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>
	</channel>
</rss>
