<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="/xsl/rss.xsl" type="text/xsl" media="screen"?>
<!--åå®¢åå«æ¥å¿ï¼æ¯äºèç½ä¸ä¸ç§ä¸ªäººä¹¦ååäººéäº¤æµçå·¥å·ãéè¿åå®¢è®°å½ä¸å·¥ä½ãå­¦ä¹ ãçæ´»åå¨±ä¹çç¹æ»´ï¼çè³è§ç¹åè¯è®ºï¼ä»èå¨ç½ä¸å»ºç«ä¸ä¸ªå®å¨å±äºèªå·±çä¸ªäººå¤©å°ãå»ºç«åå®¢ï¼æå©äºä»äººå¨äºèç½ä¸æ´å¥½å°è®¤è¯æ¨ï¼ä¹æå©äºæ¨æ´å¥½çåå«äººäº¤æµãåå®¢ä¸çæ¯ä¸ä¸ªå¼æ¾åå±äº«çä¸çãæçåå®¢ç±æçå¬å¸å¼åï¼ç®åæ¯åè´¹æå¡ã--> 
<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/"
	>

	<channel>
		<title>涛涛</title>
		<link>http://zhtxc.blog.sohu.com/</link>
		<description><![CDATA[朋友就是把你看透了　还能喜欢你的人]]></description>
		<pubDate>Sun, 28 Sep 2008 12:00:36 +0800</pubDate>
		<generator>搜狐博客</generator>
		<image>
			<title>http://blog.sohu.com</title>
			<url>http://js.pp.sohu.com/ppp/blog/images/common/logo_150_60.gif</url>
			<link>http://blog.sohu.com/</link>
			<width>100</width>
			<height>43</height>
			<description>搜狐博客</description>
		</image>
		<item>
			<title>转载： sphinx 搜索引擎</title>
			<link>http://zhtxc.blog.sohu.com/100851479.html</link>
			<comments>http://zhtxc.blog.sohu.com/100851479.html#comment</comments>
			<dc:creator>涛涛</dc:creator>
			<pubDate>Sun, 28 Sep 2008 12:00:36 +0800</pubDate>
			<category>java</category>
			<guid>http://zhtxc.blog.sohu.com/100851479.html</guid>
			<description><![CDATA[<p>原文：<a href="http://blog.s135.com/read.php/360.htm" target="_blank">http://blog.s135.com/read.php/360.htm</a></p>
<p><strong>前言</strong>：</p>
<p>本文阐述的是一款经过生产环境检验的千万级数据全文检索（搜索引擎）架构。本文只列出前几章的内容节选，不提供全文内容。</p>
<p>在DELL PowerEdge 6850服务器（四颗64 位Inter Xeon MP 7110N处理器 / 8GB内存）、RedHat
AS4 Linux操作系统、MySQL
5.1.26、MyISAM存储引擎、key_buffer=1024M环境下实测，单表1000万条记录的数据量（这张MySQL表拥有int、
datetime、varchar、text等类型的10多个字段，只有主键，无其它索引），用主键（PRIMARY
KEY）作为WHERE条件进行SQL查询，速度非常之快，只耗费0.01秒。</p>
<p>出自俄罗斯的开源全文搜索引擎软件 <a href="http://www.sphinxsearch.com/" target="_blank">Sphinx</a>
，单一索引最大可包含1亿条记录，在1千万条记录情况下的查询速度为0.x秒（毫秒级）。Sphinx创建索引的速度为：创建100万条记录的索引只需
3～4分钟，创建1000万条记录的索引可以在50分钟内完成，而只包含最新10万条记录的增量索引，重建一次只需几十秒。</p>
<p>基于以上几点，我设计出了这套搜索引擎架构。在生产环境运行了一周，效果非常不错。有时间我会专为配合Sphinx搜索引擎，开发一个逻辑简单、速
度快、占用内存低、非表锁的MySQL存储引擎插件，用来代替MyISAM引擎，以解决MyISAM存储引擎在频繁更新操作时的锁表延迟问题。另外，分布
式搜索技术上已无任何问题。</p>
<p><strong>一、搜索引擎架构设计</strong>：</p>
<p><strong>1、搜索引擎架构图</strong>：</p>
<p align="center"><img src="http://www.blueidea.com/articleimg/2008/07/6025/01.png" border="0" height="483" width="425" /></p>
<p><strong>2、搜索引擎架构设计思路</strong>：</p>
<p><strong>(1)、调用方式最简化</strong>：</p>
<p>尽量方便前端Web工程师，只需要一条简单的SQL语句&ldquo;SELECT ... FROM myisam_table JOIN
sphinx_table ON (sphinx_table.sphinx_id=myisam_table.id) WHERE
query='...';&rdquo;即可实现高效搜索。</p>
<p><strong>(2)、创建索引、查询速度快</strong>：</p>
<p>①、Sphinx Search 是由俄罗斯人Andrew Aksyonoff 开发的高性能全文搜索软件包，在GPL与商业协议双许可协议下发行。</p>
<p><strong>Sphinx的特征</strong>：</p>
<ul><li>Sphinx支持高速建立索引（可达10MB/秒，而Lucene建立索引的速度是1.8MB/秒） 
</li><li>高性能搜索（在2-4 GB的文本上搜索，平均0.1秒内获得结果） 
</li><li>高扩展性（实测最高可对100GB的文本建立索引，单一索引可包含1亿条记录） 
</li><li>支持分布式检索 
</li><li>支持基于短语和基于统计的复合结果排序机制 
</li><li>支持任意数量的文件字段（数值属性或全文检索属性） 
</li><li>支持不同的搜索模式（&ldquo;完全匹配&rdquo;，&ldquo;短语匹配&rdquo;和&ldquo;任一匹配&rdquo;） 
</li><li>支持作为Mysql的存储引擎</li></ul>
<p>②、通过国外《High Performance MySQL》专家组的测试可以看出，根据主键进行查询的类似&ldquo;SELECT ... FROM
... WHERE id = ...&rdquo;的SQL语句（其中id为PRIMARY
KEY），每秒钟能够处理10000次以上的查询，而普通的SELECT查询每秒只能处理几十次到几百次：</p>
<p align="center"><img src="http://www.blueidea.com/articleimg/2008/07/6025/02.png" border="0" height="224" width="373" /></p>
<p>③、Sphinx不负责文本字段的存储。假设将数据库的id、date、title、body字段，用sphinx建立搜索索引。根据关键字、时
间、类别、范围等信息查询一下sphinx，sphinx只会将查询结果的ID号等非文本信息告诉我们。要显示title、body等信息，还需要根据此
ID号去查询MySQL数据库，或者从Memcachedb等其他的存储中取得。安装SphinxSE作为MySQL的存储引擎，将MySQL与
Sphinx结合起来，是一种便捷的方法。</p>
<p>创建一张Sphinx类型表，将MyISAM表的主键ID和Sphinx表的ID作一个JOIN联合查询。这样，对于MyISAM表来所，只相当于
一个WHERE id=...的主键查询，WHERE后的条件都交给Sphinx去处理，可以充分发挥两者的优势，实现高速搜索查询。</p>
<p><strong>(3)、按服务类型进行分离</strong>：</p>
<p>为了保证数据的一致性，我在配置Sphinx读取索引源的MySQL数据库时，进行了锁表。Sphinx读取索引源的过程会耗费一定时间，由于
MyISAM存储引擎的读锁和写锁是互斥的，为了避免写操作被长时间阻塞，导致数据库同步落后跟不上，我将提供&ldquo;搜索查询服务&rdquo;的和提供&ldquo;索引源服务&rdquo;的
MySQL数据库进行了分开。监听3306端口的MySQL提供&ldquo;搜索查询服务&rdquo;，监听3406端口的MySQL提供&ldquo;索引源服务&rdquo;。</p>
<p><strong>(4)、&ldquo;主索引＋增量索引&rdquo;更新方式</strong>：</p>
<p>一般网站的特征：信息发布较为频繁；刚发布完的信息被编辑、修改的可能性大；两天以前的老帖变动性较小。</p>
<p>基于这个特征，我设计了Sphinx主索引和增量索引。对于前天17:00之前的记录建立主索引，每天凌晨自动重建一次主索引；对于前天17:00之后到当前最新的记录，间隔3分钟自动重建一次增量索引。</p>
<p><strong>(5)、&ldquo;Ext3文件系统＋tmpfs内存文件系统&rdquo;相结合</strong>：</p>
<p>为了避免每3分钟重建增量索引导致磁盘IO较重，从而引起系统负载上升，我将主索引文件创建在磁盘，增量索引文件创建在tmpfs内存文件系统
&ldquo;/dev/shm/&rdquo;内。&ldquo;/dev/shm/&rdquo;内的文件全部驻留在内存中，读写速度非常快。但是，重启服务器会导致&ldquo;/dev/shm/&rdquo;内的文件丢
失，针对这个问题，我会在服务器开机时自动创建&ldquo;/dev/shm/&rdquo;内目录结构和Sphinx增量索引。</p>
<p><strong>(6)、中文分词词库</strong>：</p>
<p>我根据&ldquo;百度早期中文分词库&rdquo;＋&ldquo;搜狗拼音输入法细胞词库&rdquo;＋&ldquo;LibMMSeg高频字库&rdquo;＋... 综合整理成一份中文分词词库，出于某些考虑暂不提供。你可以使用LibMMSeg自带的中文分词词库。</p>]]></description>
		</item>
		    
		
		<item>
			<title>commons DBCP 配置参数</title>
			<link>http://zhtxc.blog.sohu.com/100596095.html</link>
			<comments>http://zhtxc.blog.sohu.com/100596095.html#comment</comments>
			<dc:creator>涛涛</dc:creator>
			<pubDate>Thu, 25 Sep 2008 10:47:06 +0800</pubDate>
			<category>其他</category>
			<guid>http://zhtxc.blog.sohu.com/100596095.html</guid>
			<description><![CDATA[#连接设置<br />jdbc.driverClassName=oracle.jdbc.driver.OracleDriver<br />jdbc.url=jdbc:oracle:thin:@127.0.0.1:1521:DBSERVER<br />jdbc.username=user<br />jdbc.password=pass
<p>#&lt;!-- 初始化连接 --&gt;<br />dataSource.initialSize=10</p>
<p>#&lt;!-- 最大空闲连接 --&gt;<br />dataSource.maxIdle=20</p>
<p>#&lt;!-- 最小空闲连接 --&gt;<br />dataSource.minIdle=5</p>
<p>#最大连接数量<br />dataSource.maxActive=50</p>
<p>#是否在自动回收超时连接的时候打印连接的超时错误<br />dataSource.logAbandoned=true</p>
<p>#是否自动回收超时连接<br />dataSource.removeAbandoned=true</p>
<p>#超时时间(以秒数为单位)<br />#设置超时时间有一个要注意的地方，超时时间=现在的时间-程序中创建Connection的时间，如果
maxActive比较大，比如超过100，那么removeAbandonedTimeout可以设置长一点比如180，也就是三分钟无响应的连接进行
回收，当然应用的不同设置长度也不同。<br />dataSource.removeAbandonedTimeout=180</p>
#&lt;!-- 超时等待时间以毫秒为单位 --&gt;<br />#maxWait代表当Connection用尽了，多久之后进行回收丢失连接<br />dataSource.maxWait=1000<br />]]></description>
		</item>
		    
		
		<item>
			<title>六种用ruby调用执行shell命令的方法 </title>
			<link>http://zhtxc.blog.sohu.com/99150531.html</link>
			<comments>http://zhtxc.blog.sohu.com/99150531.html#comment</comments>
			<dc:creator>涛涛</dc:creator>
			<pubDate>Fri, 5 Sep 2008 21:40:24 +0800</pubDate>
			<category>ruby</category>
			<guid>http://zhtxc.blog.sohu.com/99150531.html</guid>
			<description><![CDATA[<br />六种用ruby调用执行shell命令的方法 <br />1.Exec方法:<br />&nbsp;&nbsp;&nbsp; Kernel#exec方法通过调用指定的命令取代当前进程：<br />&nbsp; 例子：<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $ irb<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &gt;&gt; exec 'echo &quot;hello $HOSTNAME&quot;'<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hello nate.local<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $<br />值得注意的是，exec方法用echo命令来取代了irb进程从而退出了irb。主要的缺点是，你无法从你的ruby脚本里知道这个命令是成功还是失败。<br />&nbsp;<br />2.System方法。<br />&nbsp; Kernel#system方法操作命令同上， 但是它是运行一个子shell来避免覆盖当前进程。如果命令执行成功则返回true，否则返回false。<br />&nbsp;<br />&nbsp;$ irb&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp; &gt;&gt; system 'echo &quot;hello $HOSTNAME&quot;'<br />&nbsp; hello nate.local<br />&nbsp; =&gt; true<br />&nbsp; &gt;&gt; system 'false'<br />&nbsp; =&gt; false<br />&nbsp; &gt;&gt; puts $?<br />&nbsp; 256<br />&nbsp; =&gt; nil<br />&nbsp; &gt;&gt;<br />3.反引号（Backticks，Esc键下面那个键）<br />$ irb<br />&nbsp; &gt;&gt; today = `date`<br />&nbsp; =&gt; &quot;Mon Mar 12 18:15:35 PDT 2007n&quot;<br />&nbsp; &gt;&gt; $?<br />&nbsp; =&gt; #&lt;Process::Status: pid=25827,exited(0)&gt;<br />&nbsp; &gt;&gt; $?.to_i<br />&nbsp; =&gt; 0<br />这种方法是最普遍的用法了。它也是运行在一个子shell中。<br />4.IO#popen<br />&nbsp; $ irb<br />&nbsp; &gt;&gt; IO.popen(&quot;date&quot;) { |f| puts f.gets }<br />&nbsp; Mon Mar 12 18:58:56 PDT 2007<br />&nbsp; =&gt; nil<br />5.open3#popen3<br />$ irb<br />&nbsp; &gt;&gt; stdin, stdout, stderr = Open3.popen3('dc')<br />&nbsp; =&gt; [#&lt;IO:0x6e5474&gt;, #&lt;IO:0x6e5438&gt;, #&lt;IO:0x6e53d4&gt;]<br />&nbsp; &gt;&gt; stdin.puts(5)<br />&nbsp; =&gt; nil<br />&nbsp; &gt;&gt; stdin.puts(10)<br />&nbsp; =&gt; nil<br />&nbsp; &gt;&gt; stdin.puts(&quot;+&quot;)<br />&nbsp; =&gt; nil<br />&nbsp; &gt;&gt; stdin.puts(&quot;p&quot;)<br />&nbsp; =&gt; nil<br />&nbsp; &gt;&gt; stdout.gets<br />&nbsp; =&gt; &quot;15n&quot;<br />6.Open4#popen4<br />$ irb<br />&nbsp; &gt;&gt; require &quot;open4&quot;<br />&nbsp; =&gt; true<br />&nbsp; &gt;&gt; pid, stdin, stdout, stderr = Open4::popen4 &quot;false&quot;<br />&nbsp; =&gt; [26327, #&lt;IO:0x6dff24&gt;, #&lt;IO:0x6dfee8&gt;, #&lt;IO:0x6dfe84&gt;]<br />&nbsp; &gt;&gt; $?<br />&nbsp; =&gt; nil<br />&nbsp; &gt;&gt; pid<br />&nbsp; =&gt; 26327<br />&nbsp; &gt;&gt; ignored, status = Process::waitpid2 pid<br />&nbsp; =&gt; [26327, #&lt;Process::Status: pid=26327,exited(1)&gt;]<br />&nbsp; &gt;&gt; status.to_i<br />&nbsp; =&gt; 256<br />&nbsp;<br />]]></description>
		</item>
		    
		
		<item>
			<title>http://www.javaeye.com/topic/200065</title>
			<link>http://zhtxc.blog.sohu.com/99140058.html</link>
			<comments>http://zhtxc.blog.sohu.com/99140058.html#comment</comments>
			<dc:creator>涛涛</dc:creator>
			<pubDate>Fri, 5 Sep 2008 19:22:14 +0800</pubDate>
			<guid>http://zhtxc.blog.sohu.com/99140058.html</guid>
			<description><![CDATA[http://www.javaeye.com/topic/200065]]></description>
		</item>
		    
		
		<item>
			<title>jvm参数 </title>
			<link>http://zhtxc.blog.sohu.com/97543600.html</link>
			<comments>http://zhtxc.blog.sohu.com/97543600.html#comment</comments>
			<dc:creator>涛涛</dc:creator>
			<pubDate>Mon, 18 Aug 2008 16:55:20 +0800</pubDate>
			<guid>http://zhtxc.blog.sohu.com/97543600.html</guid>
			<description><![CDATA[<p>-Xmx<br />set maximum Java heap size</p><p>-Xms<br />set initial Java heap size</p><p>-XX:MinHeapFreeRatio=40<br />Minimum percentage of heap free after GC to avoid expansion.</p><p>-XX:MaxHeapFreeRatio=70<br />Maximum percentage of heap free after GC to avoid shrinking.</p><p>-XX:NewRatio=2<br />Ratio of new/old generation sizes. [Sparc -client:8; x86 -server:8; x86 -client:12.]-client:8 (1.3.1+), x86:12]</p><p>-XX:NewSize=2.125m<br />Default size of new generation (in bytes) [5.0 and newer: 64 bit VMs are scaled 30% larger; x86:1m; x86, 5.0 and older: 640k]</p><p>-XX:MaxNewSize=<br />Maximum size of new generation (in bytes). Since 1.4, MaxNewSize is computed as a function of NewRatio.</p><p>-XX:SurvivorRatio=25<br />Ratio of eden/survivor space size [Solaris amd64: 6; Sparc in 1.3.1: 25; other Solaris platforms in 5.0 and earlier: 32]</p><p><font face="新宋体">-XX:PermSize=<br />Initial size of permanent generation</font></p><p>-XX:MaxPermSize=64m<br />Size of the Permanent Generation.&nbsp; [5.0 and newer: 64 bit VMs are scaled 30% larger; 1.4 amd64: 96m; 1.3.1 -client: 32m.]</p><br /><p><br /></p><p>堆(Heap)和非堆(Non-heap)内存
</p><p>　　按照官方的说法：&ldquo;<a href="http://www.educity.cn/incsearch/search.asp?key=Java" target="_blank">Java</a>
虚拟机具有一个堆，堆是运行时数据区域，所有类实例和数组的内存均从此处分配。堆是在 Java
虚拟机启动时创建的。&rdquo;&ldquo;在JVM中堆之外的内存称为非堆内存(Non-heap
memory)&rdquo;。可以看出JVM主要管理两种类型的内存：堆和非堆。简单来说堆就是Java代码可及的内存，是留给开发人员使用的;非堆就是JVM留给
自己用的，所以方法区、JVM内部处理或优化所需的内存(如JIT编译后的代码缓存)、每个类结构(如运行时常数池、字段和方法数据)以及方法和构造方法
的代码都在非堆内存中。</p>
<p>　　堆内存分配</p>
<p>　　JVM初始分配的内存由-Xms指定，默认是物理内存的1/64;JVM最大分配的内存由-Xmx指定，默认是物理内存的1/4。默认空余堆内
存小于40%时，JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时，JVM会减少堆直到-Xms的最小限制。因此<a href="http://www.educity.cn/incsearch/search.asp?key=%B7%FE%CE%F1%C6%F7" target="_blank">服务器</a>一般设置-Xms、-Xmx相等以避免在每次GC 后调整堆的大小。</p>
<p>　　非堆内存分配</p>
<p>　　JVM使用-XX:PermSize设置非堆内存初始值，默认是物理内存的1/64;由XX:MaxPermSize设置最大非堆内存的大小，默认是物理内存的1/4。</p>
<p>　　JVM内存限制(最大值)</p>
<p>　　首先JVM内存限制于实际的最大物理内存(废话!呵呵)，假设物理内存无限大的话，JVM内存的最大值跟<a href="http://www.educity.cn/incsearch/search.asp?key=%B2%D9%D7%F7%CF%B5%CD%B3" target="_blank">操作系统</a>有很大的关系。简单的说就32位处理器虽然可控内存空间有4GB,但是具体的操作系统会给一个限制，这个限制一般是2GB-3GB(一般来说<a href="http://www.educity.cn/incsearch/search.asp?key=Windows" target="_blank">Windows</a>系统下为1.5G-2G，<a href="http://www.educity.cn/incsearch/search.asp?key=Linux" target="_blank">Linux</a>系统下为2G-3G)，而64bit以上的处理器就不会有限制了。</p>]]></description>
		</item>
		    
		
		<item>
			<title>转载：Ruby 全局变量 </title>
			<link>http://zhtxc.blog.sohu.com/97483671.html</link>
			<comments>http://zhtxc.blog.sohu.com/97483671.html#comment</comments>
			<dc:creator>涛涛</dc:creator>
			<pubDate>Sun, 17 Aug 2008 22:31:36 +0800</pubDate>
			<category>ruby</category>
			<guid>http://zhtxc.blog.sohu.com/97483671.html</guid>
			<description><![CDATA[<h3 title=""><a href="http://sizhefang.javaeye.com/blog/25191"><span><br /></span><span></span></a></h3>
    
    
  
  
  <div>
    <span>全局变量</span>由$开头.它们可以在程序的任何位置访问到.在初始化前,<span>全局变量</span>有一个特殊的值 nil.
<br />  这里列出了一些以$打头并跟单个字符的特殊变量.比如,$$包含了<span>Ruby</span>解释器的进程id,它是只读的.这里是主要的系统变量以及它们的含义(细节可在<span>Ruby</span>的参考手册中查到):
<br />$!  最近一次的错误信息 
<br />$@  错误产生的位置 
<br />$_  gets最近读的字符串  
<br />$.  解释器最近读的行数(line number) 
<br />$&amp;  最近一次与正则表达式匹配的字符串 
<br />$~  作为子表达式组的最近一次匹配  
<br />$n  最近匹配的第n个子表达式(和$~[n]一样)  
<br />$=  是否区别大小写的标志  
<br />$/  输入记录分隔符 
<br />$\  输出记录分隔符 
<br />$0  <span>Ruby</span>脚本的文件名 
<br />$*  命令行参数 
<br />$$  解释器进程ID 
<br />$?  最近一次执行的子进程退出状态
<br />
<br />  上面的 $_ 和 $~ 都有作用范围.它们的名字暗示其为全局的,但它们一般都是这样用的,关于它们的命名有历史上的原因.
  </div>]]></description>
		</item>
		    
		
		<item>
			<title>转载：实例变量、类变量、类方法 </title>
			<link>http://zhtxc.blog.sohu.com/97482794.html</link>
			<comments>http://zhtxc.blog.sohu.com/97482794.html#comment</comments>
			<dc:creator>涛涛</dc:creator>
			<pubDate>Sun, 17 Aug 2008 22:32:00 +0800</pubDate>
			<category>ruby</category>
			<guid>http://zhtxc.blog.sohu.com/97482794.html</guid>
			<description><![CDATA[<h3 title=""><a href="http://kaichuan-zhang.javaeye.com/blog/54169"><br /></a></h3>
    
    
  
  
  
    学习编程的过程，就是深化理解变量的过程。在面向对象编程中也不例外，这一节，我们继续深化理解变量。
<br />先把 Ruby 放在一边，从编程语言的视角来探讨变量。
<br />如果一个变量，第一次赋值后，就不再允许改变变量值，这样的变量称之为常变量，简称常量。就像数学分析中的常函数，y = 3 是一个平行于 x 轴，并且函数值总是为 3 的函数。常量名用大写字母开头。
<br />如果一个变量，在其作用域上的每一个执行点，都可以改变变量值，这样的变量称之为可变量，简称变量。
<br />如果一个变量，其作用域遍及在程序的任何位置，这样的变量称之为全局变量；与之相对，作用域仅限于在程序的某一单元的变量，称之为局部变量。
<br />面向对象的编程，以类为单元模块。类是设计蓝图，具体的事物是实例对象。前面 5.3
节说到：&ldquo;变量名，变量值，变量类型，变量的作用域，是我们学习命令式语言不可回避的几个要素&rdquo;。对于面向过程的命令式语言，这四个要素已经够了；对于面
向对象的命令式语言，还要加上变量的第五个要素&mdash;&mdash;共享性。
<br />如果一个变量，只能被某个实例对象使用，这样的变量称之为实例变量；如果一个变量，能被某个类的所有实例对象共享，这样的变量称之为类变量。
<br />回到 Ruby 。常量可以定义在类和模块中，不能定义在方法中。如果在外部访问类或模块中的常量，要使用域作用符:: 。
<br />全局变量用$ 开头。
<br />实例变量，变量名用@ 开头；类变量，变量名用@@ 开头。
<br />Ruby中所说的局部变量，可以是存在于类中、方法中、模块中、一个循环中、一个过程对象中。局部变量名用小写字母开头。
<br />在4.3节，我们使用的@name（姓名）、@age（年龄）、@motherland（国籍），都是实例变量，被每个实例独享。程序 E4.3-1.rb 中，实例 p1与实例 p2的姓名不一样，年龄也不一样。
<br />如果我们希望一类事物共享某个变量，比如：在 4.4节 Student 类中，需要有一个变量来代表班级人数，实例 p3与实例 p4假使在一个班级里，班级人数这个属性应该是相同的，当然，随着 Student 类的实例不断生成，班级人数也要不断增加，如何解决呢？
<br />类变量能够很好地实现这个需求，看程序 E6.3-1.rb：
<br /><div><div><div>Ruby代码&nbsp;</div></div><ol><li><span><span>#E6.3-1.rb&nbsp;</span><span>&nbsp;&nbsp;</span></span></li><li><span><span>class</span><span>&nbsp;StudentClass&nbsp;&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;<span>@@count</span><span>=0&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;<span>def</span><span>&nbsp;initialize(&nbsp;name&nbsp;)&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span>@name</span><span>&nbsp;=&nbsp;name&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span>@@count</span><span>+=1&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;<span>end</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;<span>def</span><span>&nbsp;talk&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;puts&nbsp;<span>&quot;I&nbsp;am&nbsp;#@name,&nbsp;This&nbsp;class&nbsp;have&nbsp;#@@count&nbsp;students.&quot;</span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;<span>end</span><span>&nbsp;&nbsp;&nbsp;&nbsp;</span></span></li><li><span><span>end</span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>p1=StudentClass.<span>new</span><span>(</span><span>&quot;Student&nbsp;1&nbsp;&quot;</span><span>)&nbsp;&nbsp;</span></span></li><li><span>p2=StudentClass.<span>new</span><span>(</span><span>&quot;Student&nbsp;2&nbsp;&quot;</span><span>)&nbsp;&nbsp;</span></span></li><li><span>p3=StudentClass.<span>new</span><span>(</span><span>&quot;Student&nbsp;3&nbsp;&quot;</span><span>)&nbsp;&nbsp;</span></span></li><li><span>p4=StudentClass.<span>new</span><span>(</span><span>&quot;Student&nbsp;4&nbsp;&quot;</span><span>)&nbsp;&nbsp;</span></span></li><li><span>p3.talk&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>#&nbsp;=&gt;&nbsp;&nbsp;I&nbsp;am&nbsp;Student&nbsp;3&nbsp;,&nbsp;This&nbsp;class&nbsp;have&nbsp;4&nbsp;students.</span><span>&nbsp;&nbsp;</span></span></li><li><span>p4.talk&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>#&nbsp;=&gt;&nbsp;&nbsp;I&nbsp;am&nbsp;Student&nbsp;4&nbsp;,&nbsp;This&nbsp;class&nbsp;have&nbsp;4&nbsp;students.</span><span>&nbsp;&nbsp;</span></span></li></ol></div><pre style="display: none;">#E6.3-1.rb 
class StudentClass 
  @@count=0

  def initialize( name )
    @name = name
    @@count+=1
  end   
 
  def talk
    puts &quot;I am #@name, This class have #@@count students.&quot;
  end  
end

p1=StudentClass.new(&quot;Student 1 &quot;)
p2=StudentClass.new(&quot;Student 2 &quot;)
p3=StudentClass.new(&quot;Student 3 &quot;)
p4=StudentClass.new(&quot;Student 4 &quot;)
p3.talk         # =&gt;  I am Student 3 , This class have 4 students.
p4.talk         # =&gt;  I am Student 4 , This class have 4 students.
</pre>
<br />与全局变量和实例变量不同，类变量在使用前必须要初始化；全局变量和实例变量如果没有初始化，其值为 nil 。
<br />如果教务主任想知道某个班级现在有多少人数，不需要到这个班级去问学生，应该可以通过其它途径来获取信息。这里要用到类方法&mdash;&mdash;不依赖于任何特定
实例对象的方法。类方法与实例方法的定义方式不同，定义类方法要在方法名前加上类名和一个点号&ldquo;.&rdquo;。看程序 E6.3-2.rb：
<br /><div><div><div>Ruby代码&nbsp;</div></div><ol><li><span><span>#E6.3-2.rb&nbsp;&nbsp;</span><span>&nbsp;&nbsp;</span></span></li><li><span><span>class</span><span>&nbsp;StudentClass&nbsp;&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;<span>@@count</span><span>=0&nbsp;&nbsp;&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;<span>def</span><span>&nbsp;initialize&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span>@@count</span><span>+=1&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;<span>end</span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;<span>def</span><span>&nbsp;&nbsp;StudentClass.student_count&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;puts&nbsp;<span>&quot;This&nbsp;class&nbsp;have&nbsp;#@@count&nbsp;students.&quot;</span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;<span>end</span><span>&nbsp;&nbsp;&nbsp;&nbsp;</span></span></li><li><span><span>end</span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>p1=StudentClass.<span>new</span><span>&nbsp;&nbsp;</span></span></li><li><span>p2=StudentClass.<span>new</span><span>&nbsp;&nbsp;</span></span></li><li><span>StudentClass.student_count&nbsp;&nbsp;&nbsp;<span>#&nbsp;=&gt;&nbsp;&nbsp;This&nbsp;class&nbsp;have&nbsp;2&nbsp;students.</span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span>p3=StudentClass.<span>new</span><span>&nbsp;&nbsp;</span></span></li><li><span>p4=StudentClass.<span>new</span><span>&nbsp;&nbsp;</span></span></li><li><span>StudentClass.student_count&nbsp;&nbsp;&nbsp;<span>#&nbsp;=&gt;&nbsp;&nbsp;This&nbsp;class&nbsp;have&nbsp;4&nbsp;students.</span><span>&nbsp;&nbsp;</span></span></li></ol></div><pre style="display: none;">#E6.3-2.rb  
class StudentClass 
  @@count=0  

  def initialize
    @@count+=1
  end    

  def  StudentClass.student_count
    puts &quot;This class have #@@count students.&quot;
  end  
end

p1=StudentClass.new
p2=StudentClass.new
StudentClass.student_count   # =&gt;  This class have 2 students.

p3=StudentClass.new
p4=StudentClass.new
StudentClass.student_count   # =&gt;  This class have 4 students.
</pre>
<br />调用一个类方法，与定义类方法一样，要在方法名前加上类名和一个点号&ldquo;.&rdquo;。类方法提供了一个途径，在类的外部访问类变量，无须通过类的实例方法。
<br />类变量，类方法在 Java 里与之相对应的是 static变量，static方法。
<br />在Java里，你写一个类，是在画设计图纸，当你 new
的时候，才生成一个实例对象。Ruby语言中，一切都是对象，单个实例（具体事物）是对象，类（蓝图）也是对象。你拿着设计图纸可以生产出很多汽车，而设
计图纸对于纸来说，只是纸这类事物的一个具体实例。 Ruby里，有元类的概念，通过关键字self
与类方法的灵活使用，程序代码可以产生很多变化，这里不再展开叙述。可以思考用类方法来实现《设计模式》一书中的单子模式。]]></description>
		</item>
		    
		
		<item>
			<title>iostat    mpstat  vmstat</title>
			<link>http://zhtxc.blog.sohu.com/97377172.html</link>
			<comments>http://zhtxc.blog.sohu.com/97377172.html#comment</comments>
			<dc:creator>涛涛</dc:creator>
			<pubDate>Sat, 16 Aug 2008 12:46:19 +0800</pubDate>
			<guid>http://zhtxc.blog.sohu.com/97377172.html</guid>
			<description><![CDATA[<br />iostat -c 1 10<br />mpstat<br />vmstat<br /><br /><br />]]></description>
		</item>
		    
		
		<item>
			<title>Java Garbage Collection Tuning</title>
			<link>http://zhtxc.blog.sohu.com/95430836.html</link>
			<comments>http://zhtxc.blog.sohu.com/95430836.html#comment</comments>
			<dc:creator>涛涛</dc:creator>
			<pubDate>Thu, 24 Jul 2008 16:55:17 +0800</pubDate>
			<guid>http://zhtxc.blog.sohu.com/95430836.html</guid>
			<description><![CDATA[introduction <br />  <br /> Correctly tuning Java garbage collection is
important for high traffic web applications. This document provides
some general guidelines as well as links to additional resources. <br />  <br /> General Guidelines <br />  <br /> Server Mode <br />  <br />
For server-side applications the JVM should be run with the &quot;-server&quot;
flag. This enables the server mode for garbage collection which will
reduce the number of garbage collections to increase overall
application throughput. There is also a difference between minor and
full garbage collections in this mode. Minor garbage collections clean
up more volatile objects and take a short amount of time. Full garbage
collections take longer but run over the entire heap to clean up more
memory. <br />  <br /> Minimum and Maximum Heap Size <br />  <br /> The heap
size for the JVM should be specified based on the application's
expected memory usage. The minimum heap size is less important as it is
only useful at startup and may save a small amount of time due to fewer
garbage collection/memory allocation cycles needing to be processed.
Use -Xms(memorySize) to set the minimum heap size. For example -Xms512m
sets the minimum heap size to 512MB. <br />  <br /> The maximum heap size
is very important. If the maximum heap size is not large enough the
application can cause OutOfMemoryExceptions or there may be an
excessive number of garbage collections which will decrease application
throughput and responsiveness. However, the maximum heap should not be
set to more than 1 GB of memory unless testing has shown the JVM will
work well with a specific setting. Experience shows that the garbage
collector has difficulty with larger heap sizes. Use -Xmx(memorySize)
to set the maximum heap size. For example -Xmx1024m sets the maximum
heap size to 1024MB or 1GB. <br />  <br /> For specific recommendations on
heap sizes for Jive Software products, the general rule is that the
maximum heap size should be two to three times the total size of the
application caches. <br />  <br /> MaxPermSize <br />  <br /> The JVM stores
class metadata such as Method and Class objects in memory in the
permanent generation. The default setting for -server mode in most
environments is 64 MB (in other environments it may be 32 MB). This
setting does not generally need to be changed, but if there are
unexplained OutOfMemory exceptions after properly sizing the maximum
heap size then increasing the MaxPermSize to 128 MB is recommended.
This configuration can be done by including -XX:MaxPermSize=128m in the
JVM startup command. Note that the increased capacity will only be used
if it is needed by the JVM. <br />  <br /> Other Garbage Collection Settings <br />  <br />
There are other garbage collector settings which can make a difference
depending on the computing environment. Please see the resources
section for additional information. <br />  <br /> Garbage Collection Logging <br />  <br />
When a garbage collection issue is suspected there are several tools
which can help confirm the possibility. To log garbage collection
information, use the following two JVM command-line switches: <br />  <br /> Enable Garbage Collector Logging <br />  <br /> -verbose:gc <br />  <br /> This setting enables garbage collector logging. <br />  <br /> Log File <br />  <br /> -Xloggc:&lt;file&gt; <br />  <br />
This setting will cause the garbage collector log information to go
into the file specified by &lt;file&gt;. Note that you should copy the
garbage collection log file before restarting or else the file will get
overridden. <br />  <br /> Garbage Collection Details <br />  <br /> Using these two settings will increase the amount of helpful information in the garbage collection logs. <br />  <br /> -XX:+PrintGCTimeStamps -XX:+PrintGCDetails <br />  <br /> Garbage Collection Logging Summary <br />  <br /> Add all of these parameters to the JVM startup command: <br />  <br /> -verbose:gc -Xloggc:&lt;file&gt; -XX:+PrintGCTimeStamps -XX:+PrintGCDetails <br />  <br /> Analyzing the Garbage Collector Log Files <br />  <br />
Analyzing the garbage collector log files can be done visually by
reading the logs or with a tool such as HP's HPjtune (see the Resources
section). The format of the garbage collector logs is: <br />  <br /> &lt;timestamp&gt;: [&lt;allocation change&gt;(&lt;total heap allocated&gt;), &lt;time for garbage collection&gt;] <br />  <br />
For example, this line shows that 60.5 seconds after JVM startup a
minor garbage collection was done which tool 0.0116410 seconds and
decreased heap memory usage from 98255K to 88403K. The total heap size
allocated from the operating system is 162676K. <br />  <br /> 60.500: [98255K-&gt;88403K(162676K), 0.0116410 secs] <br />  <br />
Another example shows a full garbage collection. Full garbage
collections should happen much less frequently than minor garbage
collections. This example shows a full garbage collection that occurred
304.528 seconds after JVM startup and took 1.4657250 seconds. Heap
usage went from 47707K to 29607K out of a total allocation of 76800K. <br />  <br /> 304.528: [Full GC 47707K-&gt;29607K(76800K), 1.4657250 secs] <br />  <br /> Resources <br />  <br /> Tuning Garbage Collection with the 1.4.2 Java[tm] Virtual Machine <br /> Sun's documentation on garbage collector tuning. <br />  <br /> Tuning Garbage Collection OutlineA summary of the Sun document above. <br />  <br /> HP's HPjtune <br /> A tool from HP for visualizing garbage collection logs. <br />  <br /> Eye on performance: Tuning garbage collection in the HotSpot JVM <br /> An IBM article on garbage collector tuning. <br />  <br /> Setting up a HotSpot server or client mode on a Java 2 SDK <br /> Configuring the JVM Server Mode on IBM WebSphere Application Server
]]></description>
		</item>
		    
		
		<item>
			<title>ruby way之IO之二</title>
			<link>http://zhtxc.blog.sohu.com/94023353.html</link>
			<comments>http://zhtxc.blog.sohu.com/94023353.html#comment</comments>
			<dc:creator>涛涛</dc:creator>
			<pubDate>Tue, 15 Jul 2008 11:26:55 +0800</pubDate>
			<category>ruby</category>
			<guid>http://zhtxc.blog.sohu.com/94023353.html</guid>
			<description><![CDATA[8 执行缓冲和非缓冲的IO
<br />
<br />ruby一般使用他自己内置的缓冲:
<br />
<br /><div><div><div>Ruby代码</div></div><ol><li><span><span>print&nbsp;</span><span>&quot;Hello...&nbsp;&quot;</span><span>&nbsp;&nbsp;</span></span></li><li><span>sleep&nbsp;10&nbsp;&nbsp;</span></li><li><span>print&nbsp;<span>&quot;Goodbye!\n&quot;</span><span>&nbsp;&nbsp;</span></span></li></ol></div><pre style="display: none;">print &quot;Hello... &quot;
sleep 10
print &quot;Goodbye!\n&quot;</pre>
<br />
<br />如果你运行这个程序，你将会注意到hello,和Goodbye!\n在sleep之后同时打印到屏幕，而且Hello...后面并没有换行符.
<br />
<br />我们这时可以使用flush方法来来刷新缓冲区，在这里我们使用 $defout作为接收者：
<br />
<br /><div><div><div>Ruby代码&nbsp;</div></div><ol><li><span><span>print&nbsp;</span><span>&quot;Hello...&nbsp;&quot;</span><span>&nbsp;&nbsp;</span></span></li><li><span>STDOUT.flush&nbsp;&nbsp;</span></li><li><span>sleep&nbsp;10&nbsp;&nbsp;</span></li><li><span>print&nbsp;&quot;Goodbye!\n&nbsp;&nbsp;</span></li></ol></div><pre style="display: none;">print &quot;Hello... &quot;
STDOUT.flush
sleep 10
print &quot;Goodbye!\n</pre>
<br />
<br /> sync= 方法可以关闭缓冲，sync则可以返回此时的是否有缓冲:
<br /><div><div><div>Ruby代码&nbsp;</div></div><ol><li><span><span>buf_flag&nbsp;=&nbsp;</span><span>$defout</span><span>.sync&nbsp;&nbsp;&nbsp;&nbsp;</span><span>#&nbsp;true</span><span>&nbsp;&nbsp;</span></span></li><li><span>STDOUT.sync&nbsp;=&nbsp;<span>false</span><span>&nbsp;&nbsp;</span></span></li><li><span>buf_flag&nbsp;=&nbsp;STDOUT.sync&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>#&nbsp;false</span><span>&nbsp;&nbsp;</span></span></li></ol></div><pre style="display: none;">buf_flag = $defout.sync    # true
STDOUT.sync = false
buf_flag = STDOUT.sync     # false</pre>
<br />
<br />这里还有一个更底层的缓冲操作，getc方法返回一个字符，ungetc则将一个字符压回流:
<br /><div><div><div>Ruby代码&nbsp;</div></div><ol><li><span><span>ch&nbsp;=&nbsp;mystream.getc&nbsp;&nbsp;&nbsp;&nbsp;</span><span>#&nbsp;?A</span><span>&nbsp;&nbsp;</span></span></li><li><span>mystream.ungetc(?C)&nbsp;&nbsp;</span></li><li><span>ch&nbsp;=&nbsp;mystream.getc&nbsp;&nbsp;&nbsp;&nbsp;<span>#&nbsp;?C</span><span>&nbsp;&nbsp;</span></span></li></ol></div><pre style="display: none;">ch = mystream.getc    # ?A
mystream.ungetc(?C)
ch = mystream.getc    # ?C
</pre>
<br />
<br />这里注意，这个缓冲和上面所说的并不一样，比如sync= false并不能关掉上面的缓冲。ungetc将不能在比如sysread方法里使用，因为sysread是一个没有缓冲的读操作.
<br />
<br />9操作文件的权限和所有权
<br />
<br />为了得到一个文件的权限和所有者，我们能够是用File的uid和gid方法：
<br />
<br /><div><div><div>Ruby代码&nbsp;</div></div><ol><li><span><span>data&nbsp;=&nbsp;</span><span>File</span><span>.stat(</span><span>&quot;somefile&quot;</span><span>)&nbsp;&nbsp;</span></span></li><li><span>owner_id&nbsp;=&nbsp;data.uid&nbsp;&nbsp;</span></li><li><span>group_id&nbsp;=&nbsp;data.gid&nbsp;&nbsp;</span></li></ol></div><pre style="display: none;">data = File.stat(&quot;somefile&quot;)
owner_id = data.uid
group_id = data.gid</pre>
<br />
<br />类File::Stat 有一个实力方法mode,它返回文件的权限:
<br />
<br /><div><div><div>Ruby代码&nbsp;</div></div><ol><li><span><span>perms&nbsp;=&nbsp;</span><span>File</span><span>.stat(</span><span>&quot;somefile&quot;</span><span>).mode&nbsp;&nbsp;</span></span></li></ol></div><pre style="display: none;">perms = File.stat(&quot;somefile&quot;).mode</pre>
<br />
<br />File的chown方法能够改变一个文件的拥有者和组id:
<br />
<br /><div><div><div>Ruby代码&nbsp;</div></div><ol><li><span><span>uid&nbsp;=&nbsp;201&nbsp;&nbsp;</span></span></li><li><span>gid&nbsp;=&nbsp;10&nbsp;&nbsp;</span></li><li><span><span>File</span><span>.chown(uid,&nbsp;gid,&nbsp;</span><span>&quot;alpha&quot;</span><span>,&nbsp;</span><span>&quot;beta&quot;</span><span>)&nbsp;&nbsp;</span></span></li><li><span>f1&nbsp;=&nbsp;<span>File</span><span>.</span><span>new</span><span>(</span><span>&quot;delta&quot;</span><span>)&nbsp;&nbsp;</span></span></li><li><span>f1.chown(uid,&nbsp;gid)&nbsp;&nbsp;</span></li><li><span>f2&nbsp;=&nbsp;<span>File</span><span>.</span><span>new</span><span>(</span><span>&quot;gamma&quot;</span><span>)&nbsp;&nbsp;</span></span></li><li><span>f2.chown(<span>nil</span><span>,&nbsp;gid)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>#&nbsp;Keep&nbsp;original&nbsp;owner&nbsp;id</span><span>&nbsp;&nbsp;</span></span></li></ol></div><pre style="display: none;">uid = 201
gid = 10
File.chown(uid, gid, &quot;alpha&quot;, &quot;beta&quot;)
f1 = File.new(&quot;delta&quot;)
f1.chown(uid, gid)
f2 = File.new(&quot;gamma&quot;)
f2.chown(nil, gid)      # Keep original owner id</pre>
<br />
<br /> chmod 方法能够改变一个文件的权限：
<br />
<br /><div><div><div>Ruby代码&nbsp;</div></div><ol><li><span><span>File</span><span>.chmod(0644,&nbsp;</span><span>&quot;epsilon&quot;</span><span>,&nbsp;</span><span>&quot;theta&quot;</span><span>)&nbsp;&nbsp;</span></span></li><li><span>f&nbsp;=&nbsp;<span>File</span><span>.</span><span>new</span><span>(</span><span>&quot;eta&quot;</span><span>)&nbsp;&nbsp;</span></span></li><li><span>f.chmod(0444)&nbsp;&nbsp;</span></li></ol></div><pre style="display: none;">File.chmod(0644, &quot;epsilon&quot;, &quot;theta&quot;)
f = File.new(&quot;eta&quot;)
f.chmod(0444)</pre>
<br />
<br />我们经常需要知道某个文件，我们是否有读或者写的权限，我们可以使用File::Stat类的一些实例方法:
<br />
<br /><div><div><div>Ruby代码&nbsp;</div></div><ol><li><span><span>info&nbsp;=&nbsp;</span><span>File</span><span>.stat(</span><span>&quot;/tmp/secrets&quot;</span><span>)&nbsp;&nbsp;</span></span></li><li><span>rflag&nbsp;=&nbsp;info.readable?&nbsp;&nbsp;</span></li><li><span>wflag&nbsp;=&nbsp;info.writable?&nbsp;&nbsp;</span></li><li><span>xflag&nbsp;=&nbsp;info.executable?&nbsp;&nbsp;</span></li></ol></div><pre style="display: none;">info = File.stat(&quot;/tmp/secrets&quot;)
rflag = info.readable?
wflag = info.writable?
xflag = info.executable?</pre>
<br />
<br />有时我们需要区分有效的用户id,和实际的用户id,我们可以使用readable_real?, writable_real?, 和 executable_real?:
<br /><div><div><div>Ruby代码&nbsp;</div></div><ol><li><span><span>info&nbsp;=&nbsp;</span><span>File</span><span>.stat(</span><span>&quot;/tmp/secrets&quot;</span><span>)&nbsp;&nbsp;</span></span></li><li><span>rflag2&nbsp;=&nbsp;info.readable_real?&nbsp;&nbsp;</span></li><li><span>wflag2&nbsp;=&nbsp;info.writable_real?&nbsp;&nbsp;</span></li><li><span>xflag2&nbsp;=&nbsp;info.executable_real?&nbsp;&nbsp;</span></li></ol></div><pre style="display: none;">info = File.stat(&quot;/tmp/secrets&quot;)
rflag2 = info.readable_real?
wflag2 = info.writable_real?
xflag2 = info.executable_real?</pre>
<br />
<br />可以通过比较当前进程的有效用户ID（和组ID）来测试文件的所有权,File::Stat类有实例方法 owned?和grpowned?
<br />
<br />注意这些方法，很多在FileTest里面也有:
<br />
<br />  <div><div><div>Ruby代码&nbsp;</div></div><ol><li><span><span>rflag&nbsp;=&nbsp;FileTest:</span><span>:readable</span><span>?(</span><span>&quot;pentagon_files&quot;</span><span>)&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span>#&nbsp;Other&nbsp;methods&nbsp;are:&nbsp;writable?&nbsp;executable?&nbsp;readable_real?</span><span>&nbsp;&nbsp;</span></span></li><li><span>writable_real?&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span>#&nbsp;executable_real?&nbsp;owned?&nbsp;grpowned?</span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span>#&nbsp;Not&nbsp;found&nbsp;here:&nbsp;uid&nbsp;gid&nbsp;mode</span><span>&nbsp;&nbsp;</span></span></li></ol></div><pre style="display: none;">rflag = FileTest::readable?(&quot;pentagon_files&quot;)
    # Other methods are: writable? executable? readable_real?
writable_real?
    # executable_real? owned? grpowned?
    # Not found here: uid gid mode</pre>
<br />
<br />和进程联系在一起的umask方法决定了一个新的文件的初始权限.(unmask的具体含义去网上搜索搜索就有了).
<br />
<br />可以通过File的类方法unmask方法来获取umask。如果指定一个参数，则umask将会被设置为这个，并且将会返回原来的umask:
<br />
<br /><div><div><div>Ruby代码&nbsp;</div></div><ol><li><span><span>File</span><span>.umask(0237)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span>#&nbsp;Set&nbsp;the&nbsp;umask</span><span>&nbsp;&nbsp;</span></span></li><li><span>current_umask&nbsp;=&nbsp;<span>File</span><span>.umask&nbsp;&nbsp;&nbsp;</span><span>#&nbsp;0237</span><span>&nbsp;&nbsp;</span></span></li></ol></div><pre style="display: none;">File.umask(0237)             # Set the umask
current_umask = File.umask   # 0237</pre>
<br />
<br />10 得到和设置时间戳信息
<br />
<br />ruby所能理解的时间戳分三种,修改时间，访问时间和改变时间.
<br />
<br />mtime, atime和ctim分别返回这三种时间:
<br />
<br /><div><div><div>Ruby代码&nbsp;</div></div><ol><li><span><span>t1&nbsp;=&nbsp;</span><span>File</span><span>.mtime(</span><span>&quot;somefile&quot;</span><span>)&nbsp;&nbsp;</span></span></li><li><span><span>#&nbsp;Thu&nbsp;Jan&nbsp;04&nbsp;09:03:10&nbsp;GMT-6:00&nbsp;2001</span><span>&nbsp;&nbsp;</span></span></li><li><span>t2&nbsp;=&nbsp;<span>File</span><span>.atime(</span><span>&quot;somefile&quot;</span><span>)&nbsp;&nbsp;</span></span></li><li><span><span>#&nbsp;Tue&nbsp;Jan&nbsp;09&nbsp;10:03:34&nbsp;GMT-6:00&nbsp;2001</span><span>&nbsp;&nbsp;</span></span></li><li><span>t3&nbsp;=&nbsp;<span>File</span><span>.ctime(</span><span>&quot;somefile&quot;</span><span>)&nbsp;&nbsp;</span></span></li><li><span><span>#&nbsp;Sun&nbsp;Nov&nbsp;26&nbsp;23:48:32&nbsp;GMT-6:00&nbsp;2000</span><span>&nbsp;&nbsp;</span></span></li></ol></div><pre style="display: none;">t1 = File.mtime(&quot;somefile&quot;)
# Thu Jan 04 09:03:10 GMT-6:00 2001
t2 = File.atime(&quot;somefile&quot;)
# Tue Jan 09 10:03:34 GMT-6:00 2001
t3 = File.ctime(&quot;somefile&quot;)
# Sun Nov 26 23:48:32 GMT-6:00 2000</pre>
<br />
<br />如果正好创建了file实例或者File:;Stat实例，则可以使用实例方法：
<br /><div><div><div>Ruby代码&nbsp;</div></div><ol><li><span><span>myfile&nbsp;=&nbsp;</span><span>File</span><span>.</span><span>new</span><span>(</span><span>&quot;somefile&quot;</span><span>)&nbsp;&nbsp;</span></span></li><li><span>t1&nbsp;=&nbsp;myfile.mtime&nbsp;&nbsp;</span></li><li><span>t2&nbsp;=&nbsp;myfile.atime&nbsp;&nbsp;</span></li><li><span>t3&nbsp;=&nbsp;myfile.ctime&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>info&nbsp;=&nbsp;myfile.stat&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>t1&nbsp;=&nbsp;info.mtime&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>t2&nbsp;=&nbsp;info.atime&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li><span>t3&nbsp;=&nbsp;info.ctime&nbsp;&nbsp;</span></li></ol></div><pre style="display: none;">myfile = File.new(&quot;somefile&quot;)
t1 = myfile.mtime
t2 = myfile.atime
t3 = myfile.ctime

info = myfile.stat

t1 = info.mtime

t2 = info.atime

t3 = info.ctime</pre>
<br />
<br />文件的访问和修改时间能够通过utime来修改:
<br /><div><div><div>Ruby代码&nbsp;</div></div><ol><li><span><span>today&nbsp;=&nbsp;</span><span>Time</span><span>.now&nbsp;&nbsp;</span></span></li><li><span>yesterday&nbsp;=&nbsp;today&nbsp;-&nbsp;86400&nbsp;&nbsp;</span></li><li><span><span>File</span><span>.utime(today,&nbsp;today,&nbsp;</span><span>&quot;alpha&quot;</span><span>)&nbsp;&nbsp;</span></span></li><li><span><span>File</span><span>.utime(today,&nbsp;yesterday,&nbsp;</span><span>&quot;beta&quot;</span><span>,&nbsp;</span><span>&quot;gamma&quot;</span><span>)&nbsp;&nbsp;</span></span></li></ol></div><pre style="display: none;">today = Time.now
yesterday = today - 86400
File.utime(today, today, &quot;alpha&quot;)
File.utime(today, yesterday, &quot;beta&quot;, &quot;gamma&quot;)</pre>
<br />
<br />由于他是同时改变两个时间，因此如果你想只改变一个的话，就要先保存:
<br />
<br /><div><div>Ruby代码&nbsp;</div></div><ol><li><span><span>mtime&nbsp;=&nbsp;</span><span>File</span><span>.mtime(</span><span>&quot;delta&quot;</span><span>)&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li><span><span>File</span><span>.utime(</span><span>Time</span><span>.now,&nbsp;mtime,&nbsp;</span><span>&quot;delta&quot;</span><span>)</span></span></li></ol>]]></description>
		</item>
		    
		
	</channel>
</rss>
