<?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>tao of yue &#187; 搜索结果  &#187;  一次</title>
	<atom:link href="http://niyue.com/?s=%E4%B8%80%E6%AC%A1&#038;feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://niyue.com</link>
	<description>literally, "way" or "path"</description>
	<lastBuildDate>Sun, 18 Apr 2010 03:28:19 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>基督山伯爵</title>
		<link>http://niyue.com/2009/11/04/the-count-of-monte-cristo/</link>
		<comments>http://niyue.com/2009/11/04/the-count-of-monte-cristo/#comments</comments>
		<pubDate>Wed, 04 Nov 2009 12:41:35 +0000</pubDate>
		<dc:creator>niyue</dc:creator>
				<category><![CDATA[other]]></category>

		<guid isPermaLink="false">http://niyue.com/?p=237</guid>
		<description><![CDATA[刚读了基督山伯爵，很好看，一条主线当中穿插了很多小故事，悬念很足的，是我最喜欢的类型的书。
书是在iPhone上用Stanza看的，最后的好多章节都是在参加无聊的ISO培训期间看的。一共就十几个人参加的一个培训，早已预计到是一个很浪费生命的一次活动，本来想拿出笔记本电脑干活的，不过参加的人不多，大家都假装很认真在听的样子，我也就没好意思厚起脸皮。退而求其次的，偷偷的用iPhone看了一整天的书把后面的章节都看掉了。无聊期间，还把书中的人物关系画了一个图，用的图纸是ISO培训教材的大片空白处。书里的人物关系还是挺复杂的，外国人的人名看起来也不是很有感觉（尤其是翻译成中文之后的人名），画起图可以整理整理书中的头绪，越复杂觉得越有意思，把一页纸都给画满了。当时就觉得这个图是满有意思的一个图，想回去整理后电子化一下。
回来之后，又看了百度百科和中文的wikipedia温习了一下，上面写的还不少，都剧透光了，还好看书之前没看这些东西。然后就想到我的关系图了，我的kill time project可不能白费了心血。下载了freemind，准备用它来画这个图。开始看英文的wikipedia准备把所有的人名转换成为英文名然后放到我的图里面（因为中文名翻译出来实在差别太多，每个人的名字都有不同的叫法。像主人公，我看的版本叫做唐太斯，不过我自己觉得翻成丹迪斯好像更音近些）。wikipedia上面看着看着，突然发现原来已经有人整理过这个图了，而且写的好全面，瞬时间做这个事情的想法就化为乌有了。没有比较还好，一旦有了可参照的比较物而你又没有办法做的比它好时，你就会丧失去做一件事情的目标、心情以及动力。


]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.douban.com/subject/1261842/"><img style="float:left;padding:0 20px 20px 0;border:0" src="http://t.douban.com/lpic/s2324377.jpg" alt="" /></a>刚读了基督山伯爵，很好看，一条主线当中穿插了很多小故事，悬念很足的，是我最喜欢的类型的书。</p>
<p>书是在iPhone上用Stanza看的，最后的好多章节都是在参加无聊的ISO培训期间看的。一共就十几个人参加的一个培训，早已预计到是一个很浪费生命的一次活动，本来想拿出笔记本电脑干活的，不过参加的人不多，大家都假装很认真在听的样子，我也就没好意思厚起脸皮。退而求其次的，偷偷的用iPhone看了一整天的书把后面的章节都看掉了。无聊期间，还把书中的人物关系画了一个图，用的图纸是ISO培训教材的大片空白处。书里的人物关系还是挺复杂的，外国人的人名看起来也不是很有感觉（尤其是翻译成中文之后的人名），画起图可以整理整理书中的头绪，越复杂觉得越有意思，把一页纸都给画满了。当时就觉得这个图是满有意思的一个图，想回去整理后电子化一下。</p>
<p>回来之后，又看了百度百科和中文的wikipedia温习了一下，上面写的还不少，都剧透光了，还好看书之前没看这些东西。然后就想到我的关系图了，我的kill time project可不能白费了心血。下载了freemind，准备用它来画这个图。开始看英文的wikipedia准备把所有的人名转换成为英文名然后放到我的图里面（因为中文名翻译出来实在差别太多，每个人的名字都有不同的叫法。像主人公，我看的版本叫做唐太斯，不过我自己觉得翻成丹迪斯好像更音近些）。wikipedia上面看着看着，突然发现原来已经有人整理过这个图了，而且写的好全面，瞬时间做这个事情的想法就化为乌有了。没有比较还好，一旦有了可参照的比较物而你又没有办法做的比它好时，你就会丧失去做一件事情的目标、心情以及动力。<br />
<a href="http://upload.wikimedia.org/wikipedia/en/2/26/Countofmontecristorelations.jpg"><br />
<img class="alignnone" title="基督山伯爵关系图@Wikipedia" src="http://upload.wikimedia.org/wikipedia/en/2/26/Countofmontecristorelations.jpg" alt="" width="100%" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://niyue.com/2009/11/04/the-count-of-monte-cristo/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Snow Leopard下的中文输入法</title>
		<link>http://niyue.com/2009/08/27/snow-leopard-ime/</link>
		<comments>http://niyue.com/2009/08/27/snow-leopard-ime/#comments</comments>
		<pubDate>Thu, 27 Aug 2009 13:39:27 +0000</pubDate>
		<dc:creator>niyue</dc:creator>
				<category><![CDATA[mac]]></category>

		<guid isPermaLink="false">http://niyue.com/?p=227</guid>
		<description><![CDATA[今天刚刚安装好了Snow Leopard，晚上稍微使用了一下，从外观上和功能上并没有感到比Leopard有很大变化的地方，唯独一个例外－－中文输入法。
在10.5里面自带的中文输入法，感觉很不好用，所以后来换用了FIT。不过FIT在2008年5月之后就没有更新了，用虽然也没有什么问题，但是总是不太爽，不过比系统自带的输入法还是要好了不少，所以也就一直将就着。再后来偶遇了SunPinyin，发现在Mac下有可用的版本，于是就切换到SunPinyin，用着也还行，但是有一个缺点－－每次第一次启动的时候非常慢。免费的东西，不能要求太高，也忍了。
现在，在10.6中用自带的输入法打字，也不知道是因为和SunPinyin比较的原因，还是Snow Leopard确实在性能方面的提高，感觉输入法的召唤以及输入字符速度快了非常之多。原来10.5里面一直觉得很差劲的词组输入现在也有了很大的改善，命中率感觉好了不少，打字那真叫一个爽字。Snow Leopard里面据我所知和中文输入法相关的改进是有一个的，Apple在Snow Leopard里面还特别列出了这个号称是Innovative Chinese Character Input，其实就是使用Multi-Touch的触控板进行类似手写板的中文字符输入。再看关于Snow Leopard的review文章的时候，提到很多关于InputManager相关的应用程序在Snow Leopard上面的兼容性有些问题。所有这些，都让我们有理由相信，Snow Leopard中的输入法进行了重大的改变，从我的感觉，变得更快、更好了～

还有一点更赞的是，Snow Leopard里面的输入法切换终于不是问题了。在Leopard里面不同的程序之间的输入法状态是共享的，比方说，在Adium里面聊天的时候一般用中文，但是Firefox里面输入搜索或者输入网址的时候可能经常用英文，要是在一边聊天的时候一边上网，由于不同的应用程序之间共享了同一输入法状态，你必须要在每次切换应用的时候切换输入法，这是非常痛苦的一件事情。所以原来不得不借助InputSwitcher这一工具来减轻这一痛苦（不过有时会碰到无法切换出输入法的问题）。在Snow Leopard里面，这不是一个问题，因为操作系统中内置了选项可以让用户选择是否在不同的应用程序之间使用不同的输入源。通过&#8221;System Preferences&#8221; =&#62; &#8220;Language &#38; Texts&#8221; =&#62; &#8220;Input Sources&#8221; =&#62; &#8220;Input Source Options&#8221;即可设置:

]]></description>
			<content:encoded><![CDATA[<p>今天刚刚安装好了Snow Leopard，晚上稍微使用了一下，从外观上和功能上并没有感到比Leopard有很大变化的地方，唯独一个例外－－中文输入法。</p>
<p>在10.5里面自带的中文输入法，感觉很不好用，所以后来换用了<a href="http://fit.coollittlethings.com/">FIT</a>。不过FIT在2008年5月之后就没有更新了，用虽然也没有什么问题，但是总是不太爽，不过比系统自带的输入法还是要好了不少，所以也就一直将就着。再后来偶遇了<a href="www.opensolaris.org/os/project/input-method/">SunPinyin</a>，发现在Mac下有可用的版本，于是就切换到SunPinyin，用着也还行，但是有一个缺点－－每次第一次启动的时候非常慢。免费的东西，不能要求太高，也忍了。</p>
<p>现在，在10.6中用自带的输入法打字，也不知道是因为和SunPinyin比较的原因，还是Snow Leopard确实在性能方面的提高，感觉输入法的召唤以及输入字符速度快了非常之多。原来10.5里面一直觉得很差劲的词组输入现在也有了很大的改善，命中率感觉好了不少，打字那真叫一个爽字。Snow Leopard里面据我所知和中文输入法相关的改进是有一个的，Apple在Snow Leopard里面还特别<a href="http://www.apple.com/macosx/refinements/">列出</a>了这个号称是Innovative Chinese Character Input，其实就是使用Multi-Touch的触控板进行类似手写板的中文字符输入。再看关于Snow Leopard的<a href="http://www.engadget.com/2009/08/26/snow-leopard-review/">review文章</a>的时候，提到很多关于InputManager相关的应用程序在Snow Leopard上面的兼容性有些问题。所有这些，都让我们有理由相信，Snow Leopard中的输入法进行了重大的改变，从我的感觉，变得更快、更好了～</p>
<p><img class="alignnone" title="Snow Leopard IME" src="http://farm4.static.flickr.com/3466/3862163046_ec14101f22_o.png" alt="" width="477" height="81" /></p>
<p>还有一点更赞的是，Snow Leopard里面的输入法切换终于不是问题了。在Leopard里面不同的程序之间的输入法状态是共享的，比方说，在Adium里面聊天的时候一般用中文，但是Firefox里面输入搜索或者输入网址的时候可能经常用英文，要是在一边聊天的时候一边上网，由于不同的应用程序之间共享了同一输入法状态，你必须要在每次切换应用的时候切换输入法，这是非常痛苦的一件事情。所以原来不得不借助<a href="limechat.net/inputswitcher/">InputSwitcher</a>这一工具来减轻这一痛苦（不过有时会碰到无法切换出输入法的问题）。在Snow Leopard里面，这不是一个问题，因为操作系统中内置了选项可以让用户选择是否在不同的应用程序之间使用不同的输入源。通过&#8221;System Preferences&#8221; =&gt; &#8220;Language &amp; Texts&#8221; =&gt; &#8220;Input Sources&#8221; =&gt; &#8220;Input Source Options&#8221;即可设置:</p>
<p><img class="alignnone" title="Input Sources @ Snow Leopard" src="http://farm4.static.flickr.com/3447/3867157596_9d5c600e07.jpg" alt="" width="500" height="281" /></p>
]]></content:encoded>
			<wfw:commentRss>http://niyue.com/2009/08/27/snow-leopard-ime/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>神奇的CAPTCHA</title>
		<link>http://niyue.com/2009/05/01/captcha-system/</link>
		<comments>http://niyue.com/2009/05/01/captcha-system/#comments</comments>
		<pubDate>Fri, 01 May 2009 01:27:50 +0000</pubDate>
		<dc:creator>niyue</dc:creator>
				<category><![CDATA[other]]></category>

		<guid isPermaLink="false">http://niyue.com/?p=226</guid>
		<description><![CDATA[原来看到过一些变态的CAPTCHA系统，比如这里。不过自己碰到过的并没有，最多也就是碰到过Google的CAPTCHA类似的识别一个图片里面的字母的CAPTCHA系统（不过这些系统好像都被各种方法攻破了）。
不过前段时间为了找些资料，注册了一个公务员考试的论坛，亲身体会到了一个这样BT的CAPTCHA。

这个CAPTCHA的变态之处就在于使用的题目是公务员考试的题目，个人觉得这类考试很多题目都没有什么正确答案可言，这里的题目也不例外。我第一次答的时候就想了半天，然后填答案时没认真审题，答案还填错了。这个系统更傻X的地方在于这些题目人虽然没有办法一下想明白，但是每次注册这个论坛碰到的CAPTCHA的问题居然是一样的，也不知道他搞一个这个系统的作用是干嘛。
]]></description>
			<content:encoded><![CDATA[<p>原来看到过一些变态的<a href="http://en.wikipedia.org/wiki/Captcha" target="_blank">CAPTCHA</a>系统，比如<a href="http://www.kenengba.com/post/505.html" target="_blank">这里</a>。不过自己碰到过的并没有，最多也就是碰到过<a href="https://www.google.com/accounts/DisplayUnlockCaptcha" target="_blank">Google的CAPTCHA</a>类似的识别一个图片里面的字母的CAPTCHA系统（不过这些系统好像都被<a href="http://securitylabs.websense.com/content/Blogs/2919.aspx" target="_blank">各种方法</a><a href="http://blogs.zdnet.com/security/?p=1232" target="_blank">攻破</a>了）。</p>
<p>不过前段时间为了找些资料，注册了一个<a href="http://bbs.qzzn.com/" target="_blank">公务员考试的论坛</a>，亲身体会到了一个这样BT的CAPTCHA。</p>
<p><img src="http://farm4.static.flickr.com/3610/3489496647_82456c4997_o.png" title="神奇CAPTCHA" alt="神奇CAPTCHA" width="597" height="571" /></p>
<p>这个CAPTCHA的变态之处就在于使用的题目是公务员考试的题目，个人觉得这类考试很多题目都没有什么正确答案可言，这里的题目也不例外。我第一次答的时候就想了半天，然后填答案时没认真审题，答案还填错了。这个系统更傻X的地方在于这些题目人虽然没有办法一下想明白，但是每次注册这个论坛碰到的CAPTCHA的问题居然是一样的，也不知道他搞一个这个系统的作用是干嘛。</p>
]]></content:encoded>
			<wfw:commentRss>http://niyue.com/2009/05/01/captcha-system/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>rails file_column plugin使用</title>
		<link>http://niyue.com/2007/08/11/rails_file_column_usage/</link>
		<comments>http://niyue.com/2007/08/11/rails_file_column_usage/#comments</comments>
		<pubDate>Sat, 11 Aug 2007 14:14:55 +0000</pubDate>
		<dc:creator>niyue</dc:creator>
				<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://niyue.com/?p=207</guid>
		<description><![CDATA[Rails的file_column插件是一个简单但是功能比较完备的文件上传插件。这一插件已经有很长时间没有更新了（最后一次更新是在2005年），但是就其功能和兼容性来说，一般的使用似乎没有什么问题。其用法也相当简单，大致的看看网站上面的文档即可。但是如果要做一些自定义的工作的话，就需要直接看它的源代码了。代码量不多，包括测试代码也就10多个文件。
最容易碰到的自定义需求应该就是定制上传文件存储的位置了，默认是在public目录下根据不同的模型名称来建立目录，明显的，这很容易造成“污染”，导致public目录下面生成大量的子目录。在看了其源码之后，注释中说明是可以通过给file_column这一方法传入参数:root_path来覆盖默认值的。我将root_path设置到public目录的file子目录下，试了之后在开发模式下上传文件确实没有问题，但是进行functional testing的时候发现并不正确。我在模型中设置了对文件大小进行验证的validates_filesize_of。这一方法在测试运行时验证查找的路径是在public目录下查找，这明显是不正确的，也即，仅仅覆盖root_path参数虽然能够在开发模式下正常工作，但是functional testing有些不同，按照其注释中的说法以及源代码，进行单元测试时file_column会把RAILS_ROOT/test/tmp/file_column这一目录作为根目录，而不是RAILS_ROOT/public/。单元测试时应该在setup方法中调用setup_fixture_files，在teardown中调用teardown_fixture_files，这两个方法会把文件fixtures复制到RAILS_ROOT/test/tmp/file_column目录下测试，测试结束后就移除。但由于根目录被我们传入的参数root_path覆盖，导致测试时的代码无法通过。解决的办法有两个，一个是按照不同的运行h环境来设置根目录，代码如下： 


if RAILS_ENV != "test"
  file_column :image, {:root_path =&#62; File.join(RAILS_ROOT, "public", "files")}
end

if RAILS_ENV == "test"
  file_column :image, {
  :root_path =&#62; File.join(RAILS_ROOT, "test", "tmp", "file_column", "files")
  }
end

但是这样做也有一个缺点，那就是如果在测试模式下进行集成测试的话（如使用selenium进行测试），file_column又会到test/tmp/file_column下查找文件。这也是明显不正确的，会导致文件无法访问。另外一个做法，可以做到万无一失的&#8211;直接修改file_column这一插件的代码:-)
]]></description>
			<content:encoded><![CDATA[<p>Rails的file_column插件是一个简单但是功能比较完备的文件上传插件。这一插件已经有很长时间没有更新了（最后一次更新是在2005年），但是就其功能和兼容性来说，一般的使用似乎没有什么问题。其用法也相当简单，大致的看看网站上面的文档即可。但是如果要做一些自定义的工作的话，就需要直接看它的源代码了。代码量不多，包括测试代码也就10多个文件。</p>
<p>最容易碰到的自定义需求应该就是定制上传文件存储的位置了，默认是在public目录下根据不同的模型名称来建立目录，明显的，这很容易造成“污染”，导致public目录下面生成大量的子目录。在看了其源码之后，注释中说明是可以通过给file_column这一方法传入参数:root_path来覆盖默认值的。我将root_path设置到public目录的file子目录下，试了之后在开发模式下上传文件确实没有问题，但是进行functional testing的时候发现并不正确。我在模型中设置了对文件大小进行验证的validates_filesize_of。这一方法在测试运行时验证查找的路径是在public目录下查找，这明显是不正确的，也即，仅仅覆盖root_path参数虽然能够在开发模式下正常工作，但是functional testing有些不同，按照其注释中的说法以及源代码，进行单元测试时file_column会把RAILS_ROOT/test/tmp/file_column这一目录作为根目录，而不是RAILS_ROOT/public/。单元测试时应该在setup方法中调用setup_fixture_files，在teardown中调用teardown_fixture_files，这两个方法会把文件fixtures复制到RAILS_ROOT/test/tmp/file_column目录下测试，测试结束后就移除。但由于根目录被我们传入的参数root_path覆盖，导致测试时的代码无法通过。解决的办法有两个，一个是按照不同的运行<span>h环境来设置根目录，代码如下： </span></p>
<blockquote>
<pre>
if RAILS_ENV != "test"
  file_column :image, {:root_path =&gt; File.join(RAILS_ROOT, "public", "files")}
end</pre>
<pre>
if RAILS_ENV == "test"
  file_column :image, {
  :root_path =&gt; File.join(RAILS_ROOT, "test", "tmp", "file_column", "files")
  }
end</pre>
</blockquote>
<p>但是这样做也有一个缺点，那就是如果在测试模式下进行集成测试的话（如使用selenium进行测试），file_column又会到test/tmp/file_column下查找文件。这也是明显不正确的，会导致文件无法访问。另外一个做法，可以做到万无一失的&#8211;直接修改file_column这一插件的代码:-)</p>
]]></content:encoded>
			<wfw:commentRss>http://niyue.com/2007/08/11/rails_file_column_usage/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>可视化Java的Call Stack</title>
		<link>http://niyue.com/2007/07/01/visualize_java_call_stack/</link>
		<comments>http://niyue.com/2007/07/01/visualize_java_call_stack/#comments</comments>
		<pubDate>Sun, 01 Jul 2007 09:14:15 +0000</pubDate>
		<dc:creator>niyue</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://niyue.com/?p=205</guid>
		<description><![CDATA[Debugging DFC实在是很痛苦的一件事情，因为DFC类库十分庞大，API的层次很深，很多层次都是非常薄的对下层的一个封装。如果是DFC的使用者，只要考虑其外部接口还比较容易，但是作为API的开发者来说的话，尤其是作为一个刚入门还不太了解其内部结构的新手来说，每次都要花费很多时间在debugger上，仅仅是为了看一下一次访问的整个层次结构是什么样的。于是利用前段空下来的时间，写了一个小工具(InvokeVis)来进行Java的Call Stack的一个可视化。
目前这个工具支持四种可视化的输出格式：

普通文本格式
很简单的格式，仅仅使用缩进来表示不同层次的调用。
GraphViz Dot格式
这一格式可以使用GraphViz中的dot工具来进行转换，可以输出为gif, jpg, png, post script等多种格式。
HTML格式
这是基于Yahoo的YUI的一个HTML格式，Call Stack被可视化的表示为一颗HTML树。
XML格式
这一格式可以使用SpringGraph来进行浏览，用户可以通过Flash来交互式的浏览Call Stack。目前的代码库中自带了一个定制的SpringGraph的flash，可以查看InvokeVis输出的XML格式。 

最开始我考虑支持的最主要的格式其实是Dot格式，只希望能够输出为一般的图片就可以了。但是后来发现Dot格式输出的图片的可扩展性不是很好，尤其是对于DFC这种超级巨大的类库而言，一个简单的小程序就会输出几千个节点的图片(在用GraphViz Dot工具转化成jpg时甚至因为节点过多无法输出，只能转化成gif)，要想看清图片的细节，只能局限与整个图片的很小一部分，仅仅是窥豹一斑。于是就考虑输出为HTML树这种可以动态变化的方式来进行浏览，扩展性确实得到了很大提高，基本不管多大的节点数都不会有什么扩展性问题。但是又觉得HTML树看起来的时候的可视化效果不如dot格式转化出的图片出色，最后转而想到flash格式的输出，应该来说最后得到的flash的效果还是不错的，但是有部分功能还需要进一步完善，尤其是对现在这一flash中输出的是无向图而不是有向图（方向表示方法调用的发向, caller method -&#62; callee method）这一点很不满意，如果有时间的话会把这点先改进一下。
输出效果图：
Dot format, converted by GraphViz? into gif format:

HTML format:

XML format, visualzed with SpringGraph? flash:

]]></description>
			<content:encoded><![CDATA[<p>Debugging <a href="http://www.dmdeveloper.com/articles/dfc/" target="_blank">DFC</a>实在是很痛苦的一件事情，因为DFC类库十分庞大，API的层次很深，很多层次都是非常薄的对下层的一个封装。如果是DFC的使用者，只要考虑其外部接口还比较容易，但是作为API的开发者来说的话，尤其是作为一个刚入门还不太了解其内部结构的新手来说，每次都要花费很多时间在debugger上，仅仅是为了看一下一次访问的整个层次结构是什么样的。于是利用前段空下来的时间，写了一个小工具(<a href="http://code.google.com/p/invokevis">InvokeVis</a>)来进行Java的Call Stack的一个可视化。</p>
<p>目前这个工具支持四种可视化的输出格式：</p>
<dl>
<dt>普通文本格式</dt>
<dd>很简单的格式，仅仅使用缩进来表示不同层次的调用。</dd>
<dt>GraphViz Dot格式</dt>
<dd>这一格式可以使用<a href="http://www.graphviz.org">GraphViz</a>中的dot工具来进行转换，可以输出为gif, jpg, png, post script等多种格式。</dd>
<dt>HTML格式</dt>
<dd>这是基于Yahoo的YUI的一个HTML格式，Call Stack被可视化的表示为一颗HTML树。</dd>
<dt>XML格式</dt>
<dd>这一格式可以使用<a href="http://mark-shepherd.com/blog/springgraph-flex-component/">SpringGraph</a>来进行浏览，用户可以通过Flash来交互式的浏览Call Stack。目前的代码库中自带了一个定制的SpringGraph的flash，可以查看InvokeVis输出的XML格式。 </dd>
</dl>
<p>最开始我考虑支持的最主要的格式其实是Dot格式，只希望能够输出为一般的图片就可以了。但是后来发现Dot格式输出的图片的可扩展性不是很好，尤其是对于DFC这种超级巨大的类库而言，一个简单的小程序就会输出几千个节点的图片(在用GraphViz Dot工具转化成jpg时甚至因为节点过多无法输出，只能转化成gif)，要想看清图片的细节，只能局限与整个图片的很小一部分，仅仅是窥豹一斑。于是就考虑输出为HTML树这种可以动态变化的方式来进行浏览，扩展性确实得到了很大提高，基本不管多大的节点数都不会有什么扩展性问题。但是又觉得HTML树看起来的时候的可视化效果不如dot格式转化出的图片出色，最后转而想到flash格式的输出，应该来说最后得到的flash的效果还是不错的，但是有部分功能还需要进一步完善，尤其是对现在这一flash中输出的是无向图而不是有向图（方向表示方法调用的发向, caller method -&gt; callee method）这一点很不满意，如果有时间的话会把这点先改进一下。<br />
输出效果图：</p>
<p>Dot format, converted by GraphViz<a href="/p/invokevis/w/edit/GraphViz">?</a> into gif format:</p>
<p><a href="http://www.yupoo.com/photos/view?id=ff808081137c1181011380c645b207f0" rel="nofollow"><img src="http://photo6.yupoo.com/20070701/155443_1170040646_m.jpg" border="0" /></a></p>
<p>HTML format:</p>
<p><a href="http://www.yupoo.com/photos/view?id=ff808081137c1181011380c6410b07ed" rel="nofollow"><img src="http://photo8.yupoo.com/20070701/155442_1860354405_m.jpg" border="0" /></a></p>
<p>XML format, visualzed with SpringGraph<a href="/p/invokevis/w/edit/SpringGraph">?</a> flash:</p>
<p><a href="http://www.yupoo.com/photos/view?id=ff808081137c1181011380c6441107ef" rel="nofollow"><img src="http://photo8.yupoo.com/20070701/155442_432715841_m.jpg" border="0" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://niyue.com/2007/07/01/visualize_java_call_stack/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Vim extremely boosts my productivity!!!</title>
		<link>http://niyue.com/2006/07/26/vim-extremely-boosts-my-productivity/</link>
		<comments>http://niyue.com/2006/07/26/vim-extremely-boosts-my-productivity/#comments</comments>
		<pubDate>Wed, 26 Jul 2006 07:53:44 +0000</pubDate>
		<dc:creator>niyue</dc:creator>
				<category><![CDATA[learning]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://niyue.com/?p=191</guid>
		<description><![CDATA[使用Vim大概半年时间了,终于可以算走过了Vim最陡峭的那段学习曲线,现在越来越感觉到它的效率了.今天使用vim完成的一个工作真正体现了这一点。
这次的工作是要比较两个列表中的人名，看列表一中的人名是否在列表二中，每个人名占了一行。如果用一般的编辑器可就麻烦了，只能用鼠标选中列表一中的某一行，然后Ctrl+C,然后Ctrl+F,然后Ctrl+V,然后Enter查找是不是有相同的字符串在第二个列表中也有出现。第一个列表一共大概有80个人，都要这样来一遍可是非常痛苦的一件事情。于是Google了一下找到了一个vim approach来完成，效率和准确率都提高了不少。我是这样做的：

normal mode: q a
0 v $ h y j
:%s/Ctrl+R  &#8220;/&#038;/g Enter
q

以后查找每一行只要按@a就可以知道在列表二里面是不是有相同的人,如果有会高亮显示并且跳到列表二的这个人名，再按一次n又回回到列表一，没有比这个更方便的更好的效果了:-)
不过要克服前面的这个学习曲线可是很累人的一件事情，不过相信vim会给你带来回报的~

]]></description>
			<content:encoded><![CDATA[<p>使用Vim大概半年时间了,终于可以算走过了Vim最陡峭的那段学习曲线,现在越来越感觉到它的效率了.今天使用vim完成的一个工作真正体现了这一点。</p>
<p>这次的工作是要比较两个列表中的人名，看列表一中的人名是否在列表二中，每个人名占了一行。如果用一般的编辑器可就麻烦了，只能用鼠标选中列表一中的某一行，然后Ctrl+C,然后Ctrl+F,然后Ctrl+V,然后Enter查找是不是有相同的字符串在第二个列表中也有出现。第一个列表一共大概有80个人，都要这样来一遍可是非常痛苦的一件事情。于是Google了一下找到了一个vim approach来完成，效率和准确率都提高了不少。我是这样做的：</p>
<ol>
<li>normal mode: q a</li>
<li>0 v $ h y j</li>
<li>:%s/Ctrl+R  &#8220;/&#038;/g Enter</li>
<li>q</li>
</ol>
<p>以后查找每一行只要按@a就可以知道在列表二里面是不是有相同的人,如果有会高亮显示并且跳到列表二的这个人名，再按一次n又回回到列表一，没有比这个更方便的更好的效果了:-)</p>
<p>不过要克服前面的这个学习曲线可是很累人的一件事情，不过相信vim会给你带来回报的~</p>
<p><img align="middle" alt="learning curve" title="learning curve" src="http://static.flickr.com/58/198654386_e221b0c933.jpg?v=0" /></p>
]]></content:encoded>
			<wfw:commentRss>http://niyue.com/2006/07/26/vim-extremely-boosts-my-productivity/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Feed Proxy</title>
		<link>http://niyue.com/2006/07/21/feed-proxy/</link>
		<comments>http://niyue.com/2006/07/21/feed-proxy/#comments</comments>
		<pubDate>Fri, 21 Jul 2006 13:19:02 +0000</pubDate>
		<dc:creator>niyue</dc:creator>
				<category><![CDATA[idea]]></category>

		<guid isPermaLink="false">http://niyue.com/?p=189</guid>
		<description><![CDATA[在我把blog迁移到自己机器的WordPress之前,我使用的是W3China的blog服务,使用的Feed服务是FeedBurner的.但是现在迁移到实验室的机器之后,没有办法使用FeedBurner了,因为这里的网络是校园网,国外没有办法访问到.
没有什么办法,只好退而求其次使用国内的FeedSky的服务,虽然支持中文好一些,但是和FeedBurner想必功能还是差了点,稳定性似乎也有些问题,不过也只能免强用了.这之后的问题是怎么处理FeedBurner上的这个feed呢?想了想还是决定指向FeedSky上面的这个feed,在做完这件事情之后突然发现,通过这一次relay,一经可以使得FeedBurner访问到我的feed信息了&#8211;使用FeedSky做一个代理.
除了我这种奇怪的需求之外,现在能想到的Feed Proxy的功能还很有限,FeedSky应该马上就会提供所谓的合烧功能,但是FeedBurner没有,这样就可以利用FeedSky的合烧mix几个Feed然后使用FeedBurner来发布:-).不过这种功能如果使用FeedDigest加上FeedBurner的话也可以实现,所以其他的功能要再发掘一下,谁有想法的请告诉我,any advice is appreciated.
]]></description>
			<content:encoded><![CDATA[<p>在我把blog迁移到自己机器的WordPress之前,我使用的是<a href="http://blogger.org.cn/blog/index.asp">W3China</a>的<a href="http://blogger.org.cn">blog服务</a>,使用的Feed服务是<a href="http://www.feedburner.com">FeedBurner</a>的.但是现在迁移到实验室的机器之后,没有办法使用FeedBurner了,因为这里的网络是校园网,国外没有办法访问到.<br />
没有什么办法,只好退而求其次使用国内的<a href="http://www.feedsky.com">FeedSky</a>的服务,虽然支持中文好一些,但是和FeedBurner想必功能还是差了点,稳定性似乎也有些问题,不过也只能免强用了.这之后的问题是怎么处理FeedBurner上的这个<a href="http://feeds.feedburner.com">feed</a>呢?想了想还是决定指向FeedSky上面的这个feed,在做完这件事情之后突然发现,通过这一次relay,一经可以使得FeedBurner访问到我的feed信息了&#8211;使用FeedSky做一个代理.<br />
除了我这种奇怪的需求之外,现在能想到的Feed Proxy的功能还很有限,FeedSky应该马上就会提供所谓的合烧功能,但是FeedBurner没有,这样就可以利用FeedSky的<a href="http://www.feedostyle.com/create_digest.aspx">合烧</a>mix几个Feed然后使用FeedBurner来发布:-).不过这种功能如果使用FeedDigest加上FeedBurner的话也可以实现,所以其他的功能要再发掘一下,谁有想法的请告诉我,any advice is appreciated.</p>
]]></content:encoded>
			<wfw:commentRss>http://niyue.com/2006/07/21/feed-proxy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>语音识别改卷系统</title>
		<link>http://niyue.com/2006/06/18/%e8%af%ad%e9%9f%b3%e8%af%86%e5%88%ab%e6%94%b9%e5%8d%b7%e7%b3%bb%e7%bb%9f/</link>
		<comments>http://niyue.com/2006/06/18/%e8%af%ad%e9%9f%b3%e8%af%86%e5%88%ab%e6%94%b9%e5%8d%b7%e7%b3%bb%e7%bb%9f/#comments</comments>
		<pubDate>Sun, 18 Jun 2006 02:24:40 +0000</pubDate>
		<dc:creator>niyue</dc:creator>
				<category><![CDATA[idea]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://niyue.com/?p=183</guid>
		<description><![CDATA[昨天帮老师改了大半天图形学的考卷,上次也改过一次,不过这次的数量可多多了.前面批的时候脑子还轻松些,到了晚上统计分数就很痛苦了,神经紧绷的算了半天,虽然都是100以内的加减法,但是终归不敢马虎大意,可能一不小心成绩就差了一个档次了.改了一个多小时,忙到9点世界杯开始才搞定.
今天事后回想了一下整个改卷的过程,突然想到要是当时找一个语音识别的工具包,利用这个工具包写一个小型语音改卷计算器,只要人工念一下10,2,5.5,8,over,就自动计算出74.5这个成绩,又准确又省力,不是很酷?不过原来只知道IBM的一个ViaVoice有这种功能,MS Office也有,不过Licence好像会有问题.今早冲到实验室立马找了一下相关的工具包,发现有不少free的Speech Recognition的工具包(Speech Recognition Software).可惜考卷已经改好了,没有动力去做些实验看看好不好用了,暂且先记下一笔.不知道高考的改卷系统里面的统计分数是如何做的呢?
Update:
今天下午老师又在进行最后的登分活动了,把所有考卷的成绩登记到成绩表上,看他登的真是那个辛苦.所有的考卷都乱序,成绩表上也是乱序,老师的做法是遍历所有的考卷,在成绩表上查找对应的学号并进行登记,时间复杂度O(n^2),方法有问题,这里应该有一个考卷登分系统,对试卷按照学号进行预排序,然后对有序数组进行二分查找只需要O(logn),n份卷子的话就是O(nlogn).对于前面的排序算法的话,人工排序好像用快排或者堆排序都不方便,用插入排序比较现实,不过也变成O(n^2)了,想了想可以用两路归并排序,人工排的话相对简单而且只要O(nlogn),这样总的时间复杂度只要O(nlogn).300份卷子每份卷子登记需要10秒的话大概可以节省14000分钟.呵呵,好像估算误差满大的,纯属娱乐锻炼下脑子.
]]></description>
			<content:encoded><![CDATA[<p>昨天帮老师改了大半天图形学的考卷,上次也改过一次,不过这次的数量可多多了.前面批的时候脑子还轻松些,到了晚上统计分数就很痛苦了,神经紧绷的算了半天,虽然都是100以内的加减法,但是终归不敢马虎大意,可能一不小心成绩就差了一个档次了.改了一个多小时,忙到9点世界杯开始才搞定.<br />
今天事后回想了一下整个改卷的过程,突然想到要是当时找一个语音识别的工具包,利用这个工具包写一个小型语音改卷计算器,只要人工念一下10,2,5.5,8,over,就自动计算出74.5这个成绩,又准确又省力,不是很酷?不过原来只知道IBM的一个ViaVoice有这种功能,MS Office也有,不过Licence好像会有问题.今早冲到实验室立马找了一下相关的工具包,发现有不少free的Speech Recognition的工具包(<a href="http://en.tldp.org/HOWTO/Speech-Recognition-HOWTO/software.html">Speech Recognition Software</a>).可惜考卷已经改好了,没有动力去做些实验看看好不好用了,暂且先记下一笔.不知道高考的改卷系统里面的统计分数是如何做的呢?</p>
<p>Update:</p>
<p>今天下午老师又在进行最后的登分活动了,把所有考卷的成绩登记到成绩表上,看他登的真是那个辛苦.所有的考卷都乱序,成绩表上也是乱序,老师的做法是遍历所有的考卷,在成绩表上查找对应的学号并进行登记,时间复杂度O(n^2),方法有问题,这里应该有一个考卷登分系统,对试卷按照学号进行预排序,然后对有序数组进行二分查找只需要O(logn),n份卷子的话就是O(nlogn).对于前面的排序算法的话,人工排序好像用快排或者堆排序都不方便,用插入排序比较现实,不过也变成O(n^2)了,想了想可以用两路归并排序,人工排的话相对简单而且只要O(nlogn),这样总的时间复杂度只要O(nlogn).300份卷子每份卷子登记需要10秒的话大概可以节省14000分钟.呵呵,好像估算误差满大的,纯属娱乐锻炼下脑子.</p>
]]></content:encoded>
			<wfw:commentRss>http://niyue.com/2006/06/18/%e8%af%ad%e9%9f%b3%e8%af%86%e5%88%ab%e6%94%b9%e5%8d%b7%e7%b3%bb%e7%bb%9f/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>怎样才能称为一次新的版本发行？</title>
		<link>http://niyue.com/2006/03/27/%e6%80%8e%e6%a0%b7%e6%89%8d%e8%83%bd%e7%a7%b0%e4%b8%ba%e4%b8%80%e6%ac%a1%e6%96%b0%e7%9a%84%e7%89%88%e6%9c%ac%e5%8f%91%e8%a1%8c%ef%bc%9f/</link>
		<comments>http://niyue.com/2006/03/27/%e6%80%8e%e6%a0%b7%e6%89%8d%e8%83%bd%e7%a7%b0%e4%b8%ba%e4%b8%80%e6%ac%a1%e6%96%b0%e7%9a%84%e7%89%88%e6%9c%ac%e5%8f%91%e8%a1%8c%ef%bc%9f/#comments</comments>
		<pubDate>Mon, 27 Mar 2006 06:23:30 +0000</pubDate>
		<dc:creator>niyue</dc:creator>
				<category><![CDATA[management]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://niyue.com/?p=168</guid>
		<description><![CDATA[今天看到了Karl Fogel写的Producing Open Source Software，有很多有用的东西，以后可以慢慢参考。刚看了几个章节，跳着看的，看到第七章“Packaging, Releasing, and Daily Development”，发现了Karl对版本发行的定义：


Old bugs have been fixed. This is probably the one thing users can count on being true of every release.
New bugs have been added. This too can usually be counted on, except sometimes in the case of security releases or other one-offs (see the section called “Security [...]]]></description>
			<content:encoded><![CDATA[<p>今天看到了<a href="http://www.red-bean.com/kfogel/">Karl Fogel</a>写的<a href="http://www.producingoss.com/">Producing Open Source Software</a>，有很多有用的东西，以后可以慢慢参考。刚看了几个章节，跳着看的，看到第七章“Packaging, Releasing, and Daily Development”，发现了Karl对版本发行的定义：</p>
<div>
<ul>
<li>Old bugs have been fixed. This is probably the one thing users can count on being true of every release.</li>
<li>New bugs have been added. This too can usually be counted on, except sometimes in the case of security releases or other one-offs (see the section called “Security Releases” later in this chapter).</li>
<li>New features may have been added.</li>
<li>New configuration options may have been added, or the meanings of old options may have changed subtly. The installation procedures may have changed slightly since the last release too, though one always hopes not.</li>
<li>Incompatible changes may have been introduced, such that the data formats used by older versions of the software are no longer useable without undergoing some sort of (possibly manual) one-way conversion step.</li>
</ul>
</div>
<p>居然有一项是“引入新的bug”，好象各种软件（比如MS的Windows）都确实符合这一条件&#8230;这才注意到好象<a href="http://www.mozcn.org/products/firefox/releases/">Release Notes</a>里面都会包含一个Known Bug之类的</p>
]]></content:encoded>
			<wfw:commentRss>http://niyue.com/2006/03/27/%e6%80%8e%e6%a0%b7%e6%89%8d%e8%83%bd%e7%a7%b0%e4%b8%ba%e4%b8%80%e6%ac%a1%e6%96%b0%e7%9a%84%e7%89%88%e6%9c%ac%e5%8f%91%e8%a1%8c%ef%bc%9f/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[转]Ant全攻略</title>
		<link>http://niyue.com/2005/04/21/%e8%bd%acant%e5%85%a8%e6%94%bb%e7%95%a5/</link>
		<comments>http://niyue.com/2005/04/21/%e8%bd%acant%e5%85%a8%e6%94%bb%e7%95%a5/#comments</comments>
		<pubDate>Wed, 20 Apr 2005 23:24:45 +0000</pubDate>
		<dc:creator>niyue</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[management]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://niyue.com/?p=131</guid>
		<description><![CDATA[Ant全攻略
转自：BEA论坛 powerise
1.Ant是什么？
Ant是一种基于Java和XML的build工具。
2 下载、安装Ant
安装Ant
下载.zip文件，解压缩到c:\ant1.3(后面引用为%ANT_HOME%)
2.1 在你运行Ant之前需要做一些配置工作。
・ 将bin目录加入PATH环境变量。
・ 设定ANT_HOME环境变量，指向你安装Ant的目录。在一些OS上，Ant的脚本可以猜测ANT_HOME（Unix和Windos NT/2000）－但最好不要依赖这一特性。
・ 可选地，设定JAVA_HOME环境变量（参考下面的高级小节），该变量应该指向你安装JDK的目录。
注意：不要将Ant的ant.jar文件放到JDK/JRE的lib/ext目录下。Ant是个应用程序，而lib/ext目录是为JDK扩展使用的（如JCE，JSSE扩展）。而且通过扩展装入的类会有安全方面的限制。
2.2 运行Ant
运行Ant非常简单，当你正确地安装Ant后，只要输入ant就可以了。
n 没有指定任何参数时，Ant会在当前目录下查询build.xml文件。如果找到了就用该文件作为buildfile。如果你用 -find 选项。Ant就会在上级目录中寻找buildfile，直至到达文件系统的根。要想让Ant使用其他的buildfile，可以用参数 -buildfile file，这里file指定了你想使用的buildfile。
n 可以指定执行一个或多个target。当省略target时，Ant使用标签&#60;project&#62;的default属性所指定的target。
命令行选项总结：
ant [options] [target [target2 [target3] &#8230;]]
Options:
-help print this message
-projecthelp print project help information
-version print the version information and exit
-quiet be extra quiet
-verbose be extra verbose
-debug print debugging information
-emacs produce logging information without adornments
-logfile file use given file for log output
-logger classname [...]]]></description>
			<content:encoded><![CDATA[<p align="center"><font color="#d52b6f">Ant全攻略</font></p>
<p align="center">转自：BEA论坛 powerise</p>
<p><font color="#0000ff">1.Ant是什么？</font><br />
Ant是一种基于Java和XML的build工具。</p>
<p><font color="#3300ff">2 下载、安装Ant</font><br />
安装Ant<br />
下载.zip文件，解压缩到c:\ant1.3(后面引用为%ANT_HOME%)</p>
<p>2.1 在你运行Ant之前需要做一些配置工作。<br />
・ 将bin目录加入PATH环境变量。<br />
・ 设定ANT_HOME环境变量，指向你安装Ant的目录。在一些OS上，Ant的脚本可以猜测ANT_HOME（Unix和Windos NT/2000）－但最好不要依赖这一特性。<br />
・ 可选地，设定JAVA_HOME环境变量（参考下面的高级小节），该变量应该指向你安装JDK的目录。<br />
注意：不要将Ant的ant.jar文件放到JDK/JRE的lib/ext目录下。Ant是个应用程序，而lib/ext目录是为JDK扩展使用的（如JCE，JSSE扩展）。而且通过扩展装入的类会有安全方面的限制。<br />
2.2 运行Ant</p>
<p>运行Ant非常简单，当你正确地安装Ant后，只要输入ant就可以了。</p>
<p>n 没有指定任何参数时，Ant会在当前目录下查询build.xml文件。如果找到了就用该文件作为buildfile。如果你用 -find 选项。Ant就会在上级目录中寻找buildfile，直至到达文件系统的根。要想让Ant使用其他的buildfile，可以用参数 -buildfile file，这里file指定了你想使用的buildfile。</p>
<p>n 可以指定执行一个或多个target。当省略target时，Ant使用标签&lt;project&gt;的default属性所指定的target。</p>
<p>命令行选项总结：<br />
ant [options] [target [target2 [target3] &#8230;]]<br />
Options:<br />
-help print this message<br />
-projecthelp print project help information<br />
-version print the version information and exit<br />
-quiet be extra quiet<br />
-verbose be extra verbose<br />
-debug print debugging information<br />
-emacs produce logging information without adornments<br />
-logfile file use given file for log output<br />
-logger classname the class that is to perform logging<br />
-listener classname add an instance of class as a project listener<br />
-buildfile file use specified buildfile<br />
-find file search for buildfile towards the root of the filesystem and use the first one found<br />
-Dproperty=value set property to value<br />
例子<br />
ant<br />
使用当前目录下的build.xml运行Ant，执行缺省的target。<br />
ant -buildfile test.xml<br />
使用当前目录下的test.xml运行Ant，执行缺省的target。<br />
ant -buildfile test.xml dist<br />
使用当前目录下的test.xml运行Ant，执行一个叫做dist的target。<br />
ant -buildfile test.xml -Dbuild=build/classes dist<br />
使用当前目录下的test.xml运行Ant，执行一个叫做dist的target，并设定build属性的值为build/classes。</p>
<p><font color="#0000ff">3 编写build.xml</font></p>
<p>Ant的buildfile是用XML写的。每个buildfile含有一个project。</p>
<p>buildfile中每个task元素可以有一个id属性，可以用这个id值引用指定的任务。这个值必须是唯一的。（详情请参考下面的Task小节）</p>
<p>3.1 Projects</p>
<p>project有下面的属性：<br />
Attribute Description Required<br />
name 项目名称. No<br />
default 当没有指定target时使用的缺省target Yes<br />
basedir 用于计算所有其他路径的基路径。该属性可以被basedir property覆盖。当覆盖时，该属性被忽略。如果属性和basedir property都没有设定，就使用buildfile文件的父目录。 No<br />
项目的描述以一个顶级的&lt;description&gt;元素的形式出现（参看description小节）。</p>
<p>一个项目可以定义一个或多个target。一个target是一系列你想要执行的。执行Ant时，你可以选择执行那个target。当没有给定target时，使用project的default属性所确定的target。</p>
<p>3.2 Targets</p>
<p>一个target可以依赖于其他的target。例如，你可能会有一个target用于编译程序，一个target用于生成可执行文件。你在生成可执行文件之前必须先编译通过，所以生成可执行文件的target依赖于编译target。Ant会处理这种依赖关系。</p>
<p>然而，应当注意到，Ant的depends属性只指定了target应该被执行的顺序－如果被依赖的target无法运行，这种depends对于指定了依赖关系的target就没有影响。</p>
<p>Ant会依照depends属性中target出现的顺序（从左到右）依次执行每个target。然而，要记住的是只要某个target依赖于一个target，后者就会被先执行。<br />
&lt;target name=&#8221;A&#8221;/&gt;<br />
&lt;target name=&#8221;B&#8221; depends=&#8221;A&#8221;/&gt;<br />
&lt;target name=&#8221;C&#8221; depends=&#8221;B&#8221;/&gt;<br />
&lt;target name=&#8221;D&#8221; depends=&#8221;C,B,A&#8221;/&gt;<br />
假定我们要执行target D。从它的依赖属性来看，你可能认为先执行C，然后B，最后A被执行。错了，C依赖于B，B依赖于A，所以先执行A，然后B，然后C，最后D被执行。</p>
<p>一个target只能被执行一次，即时有多个target依赖于它（看上面的例子）。</p>
<p>如果（或如果不）某些属性被设定，才执行某个target。这样，允许根据系统的状态（java version, OS, 命令行属性定义等等）来更好地控制build的过程。要想让一个target这样做，你就应该在target元素中，加入if（或unless）属性，带上target因该有所判断的属性。例如：<br />
&lt;target name=&#8221;build-module-A&#8221; if=&#8221;module-A-present&#8221;/&gt;<br />
&lt;target name=&#8221;build-own-fake-module-A&#8221; unless=&#8221;module-A-present&#8221;/&gt;<br />
如果没有if或unless属性，target总会被执行。</p>
<p>可选的description属性可用来提供关于target的一行描述，这些描述可由-projecthelp命令行选项输出。</p>
<p>将你的tstamp task在一个所谓的初始化target是很好的做法，其他的target依赖这个初始化target。要确保初始化target是出现在其他target依赖表中的第一个target。在本手册中大多数的初始化target的名字是&#8221;init&#8221;。</p>
<p>target有下面的属性：<br />
Attribute Description Required<br />
name target的名字 Yes<br />
depends 用逗号分隔的target的名字列表，也就是依赖表。 No<br />
if 执行target所需要设定的属性名。 No<br />
unless 执行target需要清除设定的属性名。 No<br />
description 关于target功能的简短描述。 No</p>
<p>3.3 Tasks</p>
<p>一个task是一段可执行的代码。</p>
<p>一个task可以有多个属性（如果你愿意的话，可以将其称之为变量）。属性只可能包含对property的引用。这些引用会在task执行前被解析。</p>
<p>下面是Task的一般构造形式：<br />
&lt;name attribute1=&#8221;value1&#8243; attribute2=&#8221;value2&#8243; &#8230; /&gt;<br />
这里name是task的名字，attributeN是属性名，valueN是属性值。</p>
<p>有一套内置的（built-in）task，以及一些可选task，但你也可以编写自己的task。</p>
<p>所有的task都有一个task名字属性。Ant用属性值来产生日志信息。</p>
<p>可以给task赋一个id属性：<br />
&lt;taskname id=&#8221;taskID&#8221; &#8230; /&gt;<br />
这里taskname是task的名字，而taskID是这个task的唯一标识符。通过这个标识符，你可以在脚本中引用相应的task。例如，在脚本中你可以这样：<br />
&lt;script &#8230; &gt;<br />
task1.setFoo(&#8221;bar&#8221;);<br />
&lt;/script&gt;<br />
设定某个task实例的foo属性。在另一个task中（用java编写），你可以利用下面的语句存取相应的实例。<br />
project.getReference(&#8221;task1&#8243;).<br />
注意1：如果task1还没有运行，就不会被生效（例如：不设定属性），如果你在随后配置它，你所作的一切都会被覆盖。</p>
<p>注意2：未来的Ant版本可能不会兼容这里所提的属性，因为很有可能根本没有task实例，只有proxies。</p>
<p>3.4 Properties</p>
<p>一个project可以有很多的properties。可以在buildfile中用property task来设定，或在Ant之外设定。一个property有一个名字和一个值。property可用于task的属性值。这是通过将属性名放在&#8221;${&#8221;和&#8221;}&#8221;之间并放在属性值的位置来实现的。例如如果有一个property builddir的值是&#8221;build&#8221;，这个property就可用于属性值：${builddir}/classes。这个值就可被解析为build/classes。</p>
<p>内置属性</p>
<p>如果你使用了&lt;property&gt; task 定义了所有的系统属性，Ant允许你使用这些属性。例如，${os.name}对应操作系统的名字。</p>
<p>要想得到系统属性的列表可参考the Javadoc of System.getProperties。</p>
<p>除了Java的系统属性，Ant还定义了一些自己的内置属性：<br />
basedir project基目录的绝对路径 (与&lt;project&gt;的basedir属性一样)。<br />
ant.file buildfile的绝对路径。<br />
ant.version Ant的版本。<br />
ant.project.name 当前执行的project的名字；由&lt;project&gt;的name属性设定.<br />
ant.java.version Ant检测到的JVM的版本； 目前的值有&#8221;1.1&#8243;, &#8220;1.2&#8243;, &#8220;1.3&#8243; and &#8220;1.4&#8243;.</p>
<p>例子<br />
&lt;project name=&#8221;MyProject&#8221; default=&#8221;dist&#8221; basedir=&#8221;.&#8221;&gt;</p>
<p>&lt;!&#8211; set global properties for this build &#8211;&gt;<br />
&lt;property name=&#8221;src&#8221; value=&#8221;http://blogger.org.cn/blog/.&#8221;/&gt;<br />
&lt;property name=&#8221;build&#8221; value=&#8221;build&#8221;/&gt;<br />
&lt;property name=&#8221;dist&#8221; value=&#8221;dist&#8221;/&gt;</p>
<p>&lt;target name=&#8221;init&#8221;&gt;<br />
&lt;!&#8211; Create the time stamp &#8211;&gt;<br />
&lt;tstamp/&gt;<br />
&lt;!&#8211; Create the build directory structure used by compile &#8211;&gt;<br />
&lt;mkdir dir=&#8221;${build}&#8221;/&gt;<br />
&lt;/target&gt;</p>
<p>&lt;target name=&#8221;compile&#8221; depends=&#8221;init&#8221;&gt;<br />
&lt;!&#8211; Compile the java code from ${src} into ${build} &#8211;&gt;<br />
&lt;javac srcdir=&#8221;http://blogger.org.cn/blog/${src}&#8221; destdir=&#8221;http://blogger.org.cn/blog/${build}&#8221;/&gt;<br />
&lt;/target&gt;</p>
<p>&lt;target name=&#8221;dist&#8221; depends=&#8221;compile&#8221;&gt;<br />
&lt;!&#8211; Create the distribution directory &#8211;&gt;<br />
&lt;mkdir dir=&#8221;${dist}/lib&#8221;/&gt;<br />
&lt;!&#8211; Put everything in ${build} into the MyProject-${DSTAMP}.jar file &#8211;&gt;<br />
&lt;jar jarfile=&#8221;${dist}/lib/MyProject-${DSTAMP}.jar&#8221; basedir=&#8221;${build}&#8221;/&gt;<br />
&lt;/target&gt;</p>
<p>&lt;target name=&#8221;clean&#8221;&gt;<br />
&lt;!&#8211; Delete the ${build} and ${dist} directory trees &#8211;&gt;<br />
&lt;delete dir=&#8221;${build}&#8221;/&gt;<br />
&lt;delete dir=&#8221;${dist}&#8221;/&gt;<br />
&lt;/target&gt;</p>
<p>&lt;/project&gt;</p>
<p>3.5 Path-like Structures</p>
<p>你可以用&#8221;:&#8221;和&#8221;;&#8221;作为分隔符，指定类似PATH和CLASSPATH的引用。Ant会把分隔符转换为当前系统所用的分隔符。</p>
<p>当需要指定类似路径的值时，可以使用嵌套元素。一般的形式是<br />
&lt;classpath&gt;<br />
&lt;pathelement path=&#8221;${classpath}&#8221;/&gt;<br />
&lt;pathelement location=&#8221;lib/helper.jar&#8221;/&gt;<br />
&lt;/classpath&gt;<br />
location属性指定了相对于project基目录的一个文件和目录，而path属性接受逗号或分号分隔的一个位置列表。path属性一般用作预定义的路径－－其他情况下，应该用多个location属性。</p>
<p>为简洁起见，classpath标签支持自己的path和location属性。所以：<br />
&lt;classpath&gt;<br />
&lt;pathelement path=&#8221;${classpath}&#8221;/&gt;<br />
&lt;/classpath&gt;<br />
可以被简写作：<br />
&lt;classpath path=&#8221;${classpath}&#8221;/&gt;<br />
也可通过&lt;fileset&gt;元素指定路径。构成一个fileset的多个文件加入path-like structure的顺序是未定的。<br />
&lt;classpath&gt;<br />
&lt;pathelement path=&#8221;${classpath}&#8221;/&gt;<br />
&lt;fileset dir=&#8221;lib&#8221;&gt;<br />
&lt;include name=&#8221;**/*.jar&#8221;/&gt;<br />
&lt;/fileset&gt;<br />
&lt;pathelement location=&#8221;classes&#8221;/&gt;<br />
&lt;/classpath&gt;<br />
上面的例子构造了一个路径值包括：${classpath}的路径，跟着lib目录下的所有jar文件，接着是classes目录。</p>
<p>如果你想在多个task中使用相同的path-like structure，你可以用&lt;path&gt;元素定义他们（与target同级），然后通过id属性引用－－参考Referencs例子。</p>
<p>path-like structure可能包括对另一个path-like structurede的引用（通过嵌套&lt;path&gt;元素）：<br />
&lt;path id=&#8221;base.path&#8221;&gt;<br />
&lt;pathelement path=&#8221;${classpath}&#8221;/&gt;<br />
&lt;fileset dir=&#8221;lib&#8221;&gt;<br />
&lt;include name=&#8221;**/*.jar&#8221;/&gt;<br />
&lt;/fileset&gt;<br />
&lt;pathelement location=&#8221;classes&#8221;/&gt;<br />
&lt;/path&gt;<br />
&lt;path id=&#8221;tests.path&#8221;&gt;<br />
&lt;path refid=&#8221;base.path&#8221;/&gt;<br />
&lt;pathelement location=&#8221;testclasses&#8221;/&gt;<br />
&lt;/path&gt;<br />
前面所提的关于&lt;classpath&gt;的简洁写法对于&lt;path&gt;也是有效的，如：<br />
&lt;path id=&#8221;tests.path&#8221;&gt;<br />
&lt;path refid=&#8221;base.path&#8221;/&gt;<br />
&lt;pathelement location=&#8221;testclasses&#8221;/&gt;<br />
&lt;/path&gt;<br />
可写成：<br />
&lt;path id=&#8221;base.path&#8221; path=&#8221;${classpath}&#8221;/&gt;<br />
命令行变量</p>
<p>有些task可接受参数，并将其传递给另一个进程。为了能在变量中包含空格字符，可使用嵌套的arg元素。<br />
Attribute Description Required<br />
value 一个命令行变量；可包含空格字符。 只能用一个<br />
line 空格分隔的命令行变量列表。<br />
file 作为命令行变量的文件名；会被文件的绝对名替代。<br />
path 一个作为单个命令行变量的path-like的字符串；或作为分隔符，Ant会将其转变为特定平台的分隔符。</p>
<p>例子<br />
&lt;arg value=&#8221;-l -a&#8221;/&gt;<br />
是一个含有空格的单个的命令行变量。<br />
&lt;arg line=&#8221;-l -a&#8221;/&gt;<br />
是两个空格分隔的命令行变量。<br />
&lt;arg path=&#8221;/dir;/dir2:\dir3&#8243;/&gt;<br />
是一个命令行变量，其值在DOS系统上为\dir;\dir2;\dir3；在Unix系统上为/dir:/dir2:/dir3 。</p>
<p>3.6 References</p>
<p>buildfile元素的id属性可用来引用这些元素。如果你需要一遍遍的复制相同的XML代码块，这一属性就很有用－－如多次使用&lt;classpath&gt;结构。</p>
<p>下面的例子：<br />
&lt;project &#8230; &gt;<br />
&lt;target &#8230; &gt;<br />
&lt;rmic &#8230;&gt;<br />
&lt;classpath&gt;<br />
&lt;pathelement location=&#8221;lib/&#8221;/&gt;<br />
&lt;pathelement path=&#8221;${java.class.path}/&#8221;/&gt;<br />
&lt;pathelement path=&#8221;${additional.path}&#8221;/&gt;<br />
&lt;/classpath&gt;<br />
&lt;/rmic&gt;<br />
&lt;/target&gt;<br />
&lt;target &#8230; &gt;<br />
&lt;javac &#8230;&gt;<br />
&lt;classpath&gt;<br />
&lt;pathelement location=&#8221;lib/&#8221;/&gt;<br />
&lt;pathelement path=&#8221;${java.class.path}/&#8221;/&gt;<br />
&lt;pathelement path=&#8221;${additional.path}&#8221;/&gt;<br />
&lt;/classpath&gt;<br />
&lt;/javac&gt;<br />
&lt;/target&gt;<br />
&lt;/project&gt;<br />
可以写成如下形式：<br />
&lt;project &#8230; &gt;<br />
&lt;path id=&#8221;project.class.path&#8221;&gt;<br />
&lt;pathelement location=&#8221;lib/&#8221;/&gt;<br />
&lt;pathelement path=&#8221;${java.class.path}/&#8221;/&gt;<br />
&lt;pathelement path=&#8221;${additional.path}&#8221;/&gt;<br />
&lt;/path&gt;<br />
&lt;target &#8230; &gt;<br />
&lt;rmic &#8230;&gt;<br />
&lt;classpath refid=&#8221;project.class.path&#8221;/&gt;<br />
&lt;/rmic&gt;<br />
&lt;/target&gt;<br />
&lt;target &#8230; &gt;<br />
&lt;javac &#8230;&gt;<br />
&lt;classpath refid=&#8221;project.class.path&#8221;/&gt;<br />
&lt;/javac&gt;<br />
&lt;/target&gt;<br />
&lt;/project&gt;<br />
所有使用PatternSets, FileSets 或 path-like structures嵌套元素的task也接受这种类型的引用。<br />
================================================================<br />
<font color="#ee1169">Ant全攻略（续）－－－Ant中的内置任务</font></p>
<p>4.1 File（Directory）类<br />
4.1.1 Mkdir<br />
n 创建一个目录，如果他的父目录不存在，也会被同时创建。<br />
n 例子：<br />
&lt;mkdir dir=&#8221;build/classes&#8221;/&gt;<br />
n 说明： 如果build不存在，也会被同时创建<br />
4.1.2 Copy<br />
n 拷贝一个（组）文件、目录<br />
n 例子：<br />
1. 拷贝单个的文件：<br />
&lt;copy file=&#8221;myfile.txt&#8221; tofile=&#8221;mycopy.txt&#8221;/&gt;<br />
2. 拷贝单个的文件到指定目录下<br />
&lt;copy file=&#8221;myfile.txt&#8221; todir=&#8221;../some/other/dir&#8221;/&gt;<br />
3. 拷贝一个目录到另外一个目录下<br />
&lt;copy todir=&#8221;../new/dir&#8221;&gt;<br />
&lt;fileset dir=&#8221;src_dir&#8221;/&gt;<br />
&lt;/copy&gt;<br />
4. 拷贝一批文件到指定目录下<br />
&lt;copy todir=&#8221;http://blogger.org.cn/blog/../dest/dir&#8221;&gt;<br />
&lt;fileset dir=&#8221;src_dir&#8221;&gt;<br />
&lt;exclude name=&#8221;http://blogger.org.cn/blog/**/*.java&#8221;/&gt;<br />
&lt;/fileset&gt;<br />
&lt;/copy&gt;</p>
<p>&lt;copy todir=&#8221;../dest/dir&#8221;&gt;<br />
&lt;fileset dir=&#8221;src_dir&#8221; excludes=&#8221;http://blogger.org.cn/blog/**/*.java&#8221;/&gt;<br />
&lt;/copy&gt;<br />
5. 拷贝一批文件到指定目录下，将文件名后增加。Bak后缀<br />
&lt;copy todir=&#8221;../backup/dir&#8221;&gt;<br />
&lt;fileset dir=&#8221;src_dir&#8221;/&gt;<br />
&lt;mapper type=&#8221;http://blogger.org.cn/blog/glob&#8221; from=&#8221;*&#8221; to=&#8221;*.bak&#8221;/&gt;<br />
&lt;/copy&gt;<br />
6. 拷贝一组文件到指定目录下，替换其中的@标签@内容<br />
&lt;copy todir=&#8221;../backup/dir&#8221;&gt;<br />
&lt;fileset dir=&#8221;src_dir&#8221;/&gt;<br />
&lt;filterset&gt;<br />
&lt;filter token=&#8221;http://blogger.org.cn/blog/TITLE&#8221; value=&#8221;Foo Bar&#8221;/&gt;<br />
&lt;/filterset&gt;<br />
&lt;/copy&gt;<br />
4.1.3 Delete<br />
n 删除一个（组）文件或者目录<br />
n 例子<br />
1. 删除一个文件<br />
&lt;delete file=&#8221;/lib/ant.jar&#8221;/&gt;<br />
2. 删除指定目录及其子目录<br />
&lt;delete dir=&#8221;lib&#8221;/&gt;<br />
3. 删除指定的一组文件<br />
&lt;delete&gt;<br />
&lt;fileset dir=&#8221;.&#8221; includes=&#8221;**/*.bak&#8221;/&gt;<br />
&lt;/delete&gt;<br />
4. 删除指定目录及其子目录，包括他自己<br />
&lt;delete includeEmptyDirs=&#8221;true&#8221;&gt;<br />
&lt;fileset dir=&#8221;build&#8221;/&gt;<br />
&lt;/delete&gt;<br />
4.1.4 Move<br />
n 移动或重命名一个（组）文件、目录<br />
n 例子：<br />
1. 移动或重命名一个文件<br />
&lt;move file=&#8221;file.orig&#8221; tofile=&#8221;file.moved&#8221;/&gt;<br />
2. 移动或重命名一个文件到另一个文件夹下面<br />
&lt;move file=&#8221;file.orig&#8221; todir=&#8221;dir/to/move/to&#8221;/&gt;<br />
3. 将一个目录移到另外一个目录下<br />
&lt;move todir=&#8221;new/dir/to/move/to&#8221;&gt;<br />
&lt;fileset dir=&#8221;src/dir&#8221;/&gt;<br />
&lt;/move&gt;<br />
4. 将一组文件移动到另外的目录下<br />
&lt;move todir=&#8221;http://blogger.org.cn/blog/some/new/dir&#8221;&gt;<br />
&lt;fileset dir=&#8221;my/src/dir&#8221;&gt;<br />
&lt;include name=&#8221;http://blogger.org.cn/blog/**/*.jar&#8221;/&gt;<br />
&lt;exclude name=&#8221;**/ant.jar&#8221;/&gt;<br />
&lt;/fileset&gt;<br />
&lt;/move&gt;<br />
5. 移动文件过程中增加。Bak后缀<br />
&lt;move todir=&#8221;my/src/dir&#8221;&gt;<br />
&lt;fileset dir=&#8221;http://blogger.org.cn/blog/my/src/dir&#8221;&gt;<br />
&lt;exclude name=&#8221;http://blogger.org.cn/blog/**/*.bak&#8221;/&gt;<br />
&lt;/fileset&gt;<br />
&lt;mapper type=&#8221;glob&#8221; from=&#8221;*&#8221; to=&#8221;*.bak&#8221;/&gt;<br />
&lt;/move&gt;</p>
<p>================================================================<br />
<font color="#ff0099">Ant全攻略  &#8212;  Java相关任务</font><br />
4.2.1 Javac<br />
n 编译java原代码<br />
n 例子<br />
1. &lt;javac srcdir=&#8221;http://blogger.org.cn/blog/${src}&#8221;<br />
destdir=&#8221;http://blogger.org.cn/blog/${build}&#8221;<br />
classpath=&#8221;xyz.jar&#8221;<br />
debug=&#8221;on&#8221;<br />
/&gt;<br />
编译${src}目录及其子目录下的所有。Java文件，。Class文件将放在$｛build｝指定的目录下，classpath表示需要用到的类文件或者目录，debug设置为on表示输出debug信息<br />
2. &lt;javac srcdir=&#8221;http://blogger.org.cn/blog/${src}:${src2}&#8221;<br />
destdir=&#8221;http://blogger.org.cn/blog/${build}&#8221;<br />
includes=&#8221;mypackage/p1/**,mypackage/p2/**&#8221;<br />
excludes=&#8221;mypackage/p1/testpackage/**&#8221;<br />
classpath=&#8221;xyz.jar&#8221;<br />
debug=&#8221;on&#8221;<br />
/&gt;<br />
编译${src}和${src2}目录及其子目录下的所有。Java文件，但是package/p1/**,mypackage/p2/**将被编译，而mypackage/p1/testpackage/**将不会被编译。Class文件将放在$｛build｝指定的目录下，classpath表示需要用到的类文件或者目录，debug设置为on表示输出debug信息<br />
3. &lt;property name=&#8221;http://blogger.org.cn/blog/classpath&#8221; value=&#8221;.;./xml-apis.jar;../lib/xbean.jar;./easypo.jar&#8221;/&gt;</p>
<p>&lt;javac srcdir=&#8221;http://blogger.org.cn/blog/${src}&#8221;<br />
destdir=&#8221;http://blogger.org.cn/blog/${src}&#8221;<br />
classpath=&#8221;http://blogger.org.cn/blog/${classpath}&#8221;<br />
debug=&#8221;on&#8221;<br />
/&gt;<br />
路径是在property中定义的<br />
4.2.2 java<br />
n 执行指定的java类<br />
n 例子：<br />
1. &lt;java classname=&#8221;test.Main&#8221;&gt;<br />
&lt;classpath&gt;<br />
&lt;pathelement location=&#8221;dist/test.jar&#8221;/&gt;<br />
&lt;pathelement path=&#8221;${java.class.path}&#8221;/&gt;<br />
&lt;/classpath&gt;<br />
&lt;/java&gt;<br />
classname中指定要执行的类，classpath设定要使用的环境变量<br />
2. &lt;path id=&#8221;project.class.path&#8221;&gt;<br />
&lt;pathelement location=&#8221;lib/&#8221;/&gt;<br />
&lt;pathelement path=&#8221;${java.class.path}/&#8221;/&gt;<br />
&lt;pathelement path=&#8221;${additional.path}&#8221;/&gt;<br />
&lt;/path&gt;</p>
<p>&lt;target &#8230; &gt;<br />
&lt;rmic &#8230;&gt;<br />
&lt;classpath refid=&#8221;project.class.path&#8221;/&gt;<br />
&lt;/rmic&gt;<br />
&lt;/target&gt;</p>
<p>================================================================</p>
<p><font color="#f70997">Ant全攻略  &#8212;     通过JDBC执行SQL语句</font></p>
<p>4.5 执行SQL语句</p>
<p>n 通过jdbc执行SQL语句<br />
n 例子：<br />
1. &lt;sql<br />
driver=&#8221;org.gjt.mm.mysql.Driver&#8221;<br />
url=&#8221;jdbc:mysql://localhost:3306/mydb&#8221;<br />
userid=&#8221;root&#8221;<br />
password=&#8221;root&#8221;<br />
xsrc=&#8221;http://blogger.org.cn/blog/data.sql&#8221; mce_src=&#8221;http://blogger.org.cn/blog/data.sql&#8221;<br />
/&gt;<br />
2. &lt;sql<br />
driver=&#8221;org.database.jdbcDriver&#8221;<br />
url=&#8221;jdbc:database-url&#8221;<br />
userid=&#8221;sa&#8221;<br />
password=&#8221;pass&#8221;<br />
xsrc=&#8221;http://blogger.org.cn/blog/data.sql&#8221; mce_src=&#8221;http://blogger.org.cn/blog/data.sql&#8221;<br />
rdbms=&#8221;oracle&#8221;<br />
version=&#8221;8.1.&#8221;<br />
&gt;<br />
&lt;/sql&gt;<br />
只有在oracle、版本是8.1的时候才执行</p>
<p>================================================================<br />
<font color="#ff0099">Ant 全攻略之  －－－  发送邮件</font></p>
<p>4.6 发送邮件<br />
n 使用SMTP服务器发送邮件<br />
n 例子：<br />
&lt;mail mailhost=&#8221;smtp.myisp.com&#8221; mailport=&#8221;1025&#8243; subject=&#8221;Test build&#8221;&gt;<br />
&lt;from address=&#8221;<a href="mailto:me@myisp.com%22/">me@myisp.com&#8221;/</a>&gt;<br />
&lt;to address=&#8221;http://blogger.org.cn/blog/<a href="mailto:all@xyz.com%22/">all@xyz.com&#8221;/</a>&gt;<br />
&lt;message&gt;The ${buildname} nightly build has completed&lt;/message&gt;<br />
&lt;fileset dir=&#8221;http://blogger.org.cn/blog/dist&#8221;&gt;<br />
&lt;includes name=&#8221;**/*.zip&#8221;/&gt;<br />
&lt;/fileset&gt;<br />
&lt;/mail&gt;<br />
l mailhost： SMTP服务器地址<br />
l mailport： 服务器端口<br />
l subject：  主题<br />
l from：    发送人地址<br />
l to：      接受人地址<br />
l message： 发送的消息<br />
l fileset：  设置附件</p>
]]></content:encoded>
			<wfw:commentRss>http://niyue.com/2005/04/21/%e8%bd%acant%e5%85%a8%e6%94%bb%e7%95%a5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
