<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>找到</title>
    <description></description>
    <link>http://letle.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>使用JavaScript取得HTMLElement的属性要点</title>
        <author>letle</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://letle.javaeye.com">letle</a>&nbsp;
          链接：<a href="http://letle.javaeye.com/blog/210161" style="color:red;">http://letle.javaeye.com/blog/210161</a>&nbsp;
          发表时间: 2008年07月01日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          转自：http://hi.baidu.com/beanchx/blog/item/243b38f326695e53342acc49.html<br /><br /><br />&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><br />&lt;html><br />&lt;head><br />&lt;title> OffsetProperty &lt;/title><br />&lt;style type="text/css"><br />.offsetTest{<br />   margin:1px;<br />   border:1px solid #000;<br />   padding:3px;<br />   position:relative;<br />   left:20px;<br />   top:20px;<br />   z-index:5;<br />   width:500px;<br />   height:300px;<br />}<br />&lt;/style><br />&lt;/head><br /><br />&lt;body><br />&lt;div id="offset" class="offsetTest"><br />&lt;/div><br />&lt;script><br />function getAllOffsetProperty(){<br />   var result = new Array();<br />   var offset = document.getElementById("offset");<br />   result.push("offset的offsetWidth: " + offset.offsetWidth);<br />   result.push("offset的offsetHeight: " + offset.offsetHeight);<br />   result.push("offset的offsetTop:   " + offset.offsetTop);<br />   result.push("offset的offsetLeft: " + offset.offsetLeft);<br />   result.push("offset的clientWidth: " + offset.clientWidth);<br />   result.push("offset的clientHeight: " + offset.clientHeight);<br />   result.push("offset的clientTop:   " + offset.clientTop);<br />   result.push("offset的clientLeft: " + offset.clientLeft);<br />   result.push("offset的scrollWidth: " + offset.scrollWidth);<br />   result.push("offset的scrollHeight: " + offset.scrollHeight);<br />   result.push("offset的scrollTop:   " + offset.scrollTop);<br />   result.push("offset的scrollLeft: " + offset.scrollLeft);<br />   var str = result.join("&lt;br />");<br />   return str;<br />}<br />//执行两次是因为在设定之前不准确<br />function refresh(){<br />   var offset = document.getElementById("offset");<br />   offset.innerHTML = getAllOffsetProperty();<br />}<br />function getWidthAndHeight(){<br />   var offset = document.getElementById("offset");<br />   alert(offset.style.width);<br />   alert(offset.style.height);<br />}<br />&lt;/script><br />&lt;div><br />&lt;pre><br />使用JavaScript取得HTMLElement的宽度高度要点：<br />1.设置padding以及boder以后，FF会自动增长该HTMLElement的Width以及Height，而IE不会。<br />2.offsetWidth和offsetHeight比clientWidth以及clientHeight多一个border以及滚动条，但是由于FF的<br />自动增长，遵从第一条。<br />3.clientWidth以及clientHeight为不包含border的宽高度，不会出现兼容性问题，但是宽高度的数值<br />仍然遵从第一条。<br />4.scrollWidth和scrollHeight，在FF下，最小值为clientWidth和clientHeight，但是IE认为最小值为<br />页面的实际宽高度，也就是可以比clientWidth和clientHeight小，所以使用IE的时候，下面的示例点击<br />两次结果不同。<br /><br />使用JavaScript取得HTMLElement的Top以及Left要点：<br />1.offsetTop以及offsetLeft，没发现有兼容性问题。至于他们的数值不同，是因为IE以及FF默认的margin<br />不同。<br />2.在FF下，clientLeft以及clientTop是在FF3才开始支持的。若不指定style中的left以及right，在IE下面<br />为Border的宽高度，这个原因很简单，因为clientLeft与clientTop都是与相邻组件的left以及top，clientWidth<br />以及clientHeight不包含border以及滚动条，所以就是与border的距离，也就是border的宽度。<br />3.scrollTop以及scrollLeft，没发现有什么兼容性问题。<br /><br />总结：<br />1.IE和FF的宽高度取得的数值不同在于：IE认为width是整个HTMLElement的宽度，当然，不包括margin。<br />而FF认为是可见区域的宽度，也就是要除去padding、border和margin的高度。<br />2.clientLeft、clientTop在FF3开始才开始支持，所以目前还是offsetLeft以及offsetTop好用。<br />3.若width以及高度放置在class中，竟然取不到，看来yui的getStyle函数还是需要的。<br />&lt;/pre><br />&lt;/div><br />&lt;button onclick="refresh();">取得信息(IE下点击两次试试)&lt;/button><br />&lt;button onclick="getWidthAndHeight();">取得宽高度&lt;/button><br />&lt;/body><br />&lt;/html>
          <br/>
          <span style="color:red;">
            <a href="http://letle.javaeye.com/blog/210161#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 01 Jul 2008 14:59:51 +0800</pubDate>
        <link>http://letle.javaeye.com/blog/210161</link>
        <guid>http://letle.javaeye.com/blog/210161</guid>
      </item>
      <item>
        <title>前端开发站点推荐</title>
        <author>letle</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://letle.javaeye.com">letle</a>&nbsp;
          链接：<a href="http://letle.javaeye.com/blog/204777" style="color:red;">http://letle.javaeye.com/blog/204777</a>&nbsp;
          发表时间: 2008年06月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          1.http://htmlplayground.com<br />学习HTML的站点，所见即所得。<br />2.http://krook.org/jsdom/<br />JavaScript DOM API
          <br/>
          <span style="color:red;">
            <a href="http://letle.javaeye.com/blog/204777#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 17 Jun 2008 18:13:37 +0800</pubDate>
        <link>http://letle.javaeye.com/blog/204777</link>
        <guid>http://letle.javaeye.com/blog/204777</guid>
      </item>
      <item>
        <title>【转】Function,New, Constructor And Prototye In Javas</title>
        <author>letle</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://letle.javaeye.com">letle</a>&nbsp;
          链接：<a href="http://letle.javaeye.com/blog/200973" style="color:red;">http://letle.javaeye.com/blog/200973</a>&nbsp;
          发表时间: 2008年06月06日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          转自：http://maycode.com<br />提示: 简单介绍了javascript的function，new, 构造器行为，以及prototye的基础常识，如有偏颇适当处请指出，因仅为个人理解。 <br /><br />================================================================================================================<br />一. javascript函数的几个相关概念<br />================================================================================================================<br />---------------------------------------------------------------<br />概念1. 一个函数被定义, 实际上就是创建了一个Function类的对象.<br />--------------------------------------------------------------- <br /><br />在以下4种方法等效的方法定义中,可清晰看到上述结论 <br /><br />方法1(标准)<br />function showText(text)<br />{<br />    alert(test);<br />}<br />showText("hi, tomsui!~"); <br /><br />方法2<br />show = function showText(text)<br />{<br />    alert(text);<br />}<br />show("hi, tomsui!~"); <br /><br />方法3(匿名方法)<br />show = function(text)<br /> {<br />     alert(text);<br /> }<br /> show("hi, tomsui!~"); <br /><br />方法4(显式定义对象)<br />show = new Function("text","alert(text);");<br />show("hi, tomsui!~"); <br /><br />注意: 作为一个对象,肯定会有默认的toString(),可以直接打印这个对象,其实就是函数体本身:<br />      alert(show)        // function anonymous(text) { alert(text); }<br />      alert((showText))  // function showText(text)  { alert(test); } <br /><br /><br />---------------------------------------------------------------<br />概念2.  Function类的对象有一个prototype属性<br />---------------------------------------------------------------<br />这个prototype属性是一个对象: <br /><br />function showText(text)<br />{<br />    alert(test);<br />}<br />alert(showText.prototype);             // [object, Object]<br />alert(typeof(showText.prototype));     // object<br />alert(showText.prototype.constructor); // function showText(text) { alert(test); } <br /><br />  <br /><br />构造器的prototype属性作为一个object, 本身存在一个不可for-in的属性"constructor",指向该构造器本身(打印出来的话是函数体定义) <br /><br />注意: "Function类的对象",不是每一个普通对象(通过new关键字生成)都有prototype属性的! <br /><br /><br />---------------------------------------------------------------<br />概念3.  Function类的对象有一个constructor属性<br />--------------------------------------------------------------- <br /><br />function showText(text)<br />{<br />    alert(test);<br />} <br /><br />alert(showText.constructor);          // function Function() { [native code] }<br />alert(typeof(showText.constructor));  // function <br /><br />关于Function类的对象(showText函数)的constructor属性:<br />1) 是"一段不可显示的本地代码" (而不像是showText的prototype属性一样是一个对象)<br />2) 它的类型是"function" <br /><br /><br />---------------------------------------------------------------<br />总结.   prototype属性，constructor属性, construct属性 概述<br />--------------------------------------------------------------- <br /><br />如果把对象( 根据一个对象是否为Function对象 )分为两类:<br />a. 一个函数对象  (Function类的对象)<br />b. 一个普通对象  (通过new关键字结合构造函数创造的"非Function类"对象) <br /><br />那么:<br />1. 函数对象存在prototype  属性, 而普通对象不存在;<br />2. 函数对象存在constructor属性, 普通对象不存在; constructor属性的type是"function",toString后是一段“本地代码”(native)，<br />3. 普通对象存在construct  属性, 函数对象不存在; construct  属性是type是"function" ,toString后是“函数代码本身”， <br /><br />  <br /><br />================================================================================================================<br />二. javascript面向对象的几个结论(new,prototype)<br />================================================================================================================ <br /><br />---------------------------------------------------------------<br />2.1 引子<br />--------------------------------------------------------------- <br /><br />因为javascript最初设计的面向对象存在缺陷，导致如果每一个对象关于"类的方法都进行一次硬拷贝"的问题:<br />function ShowText(text)<br />{<br />    this.word = text;<br />    this.sing = function singFunction() {alert("HelloWorld!~");};<br />} <br /><br />obj1 = new ShowText("sb1");<br />obj2 = new ShowText("sb2"); <br /><br />这样的话obj1和obj2在内存中分别有一份singFunction的方法代码，显然这很sb,有两种改进方式: <br /><br />1) 外部定义函数对象，<br />function ShowText()<br />{<br />    this.sing = singFunction;<br />} <br /><br />function singFunction(){    alert("HelloWorld!~"); } <br /><br />new ShowText().sing(); <br /><br /><br />2) 利用函数对象的prototype属性<br />function ShowText()<br />{<br />}<br />ShowText.prototype.sing = function(){ alert( "HelloWorld!~");}<br />new ShowText().sing(); <br /><br /><br />---------------------------------------------------------------<br />2.2  new关键字的作用<br />--------------------------------------------------------------- <br /><br />请对比如下的例子:<br />function ShowText(text)<br />{<br />    this.word = text;<br />} <br /><br />var obj = new ShowText("hi,tomsui!~");<br />alert(obj.word);                        // "hi,tomsui!~" <br /><br />var obj2 = new Object();<br />obj2.constuct = ShowText;<br />obj2.constuct("hi,tomsui!~");<br />alert(obj2.word);                      // "hi,tomsui!~" <br /><br />通过运行结果可以看出存在如下等价关系:<br />var ball0=new Ball("creating new Ball");<br />&lt;==><br />var ball0=new Object();<br />ball0.construct=Ball;<br />ball0.construct("creating new ball"); <br /><br />分析上述等价关系,可得到"new"关键字背后的实际动作如下:<br />a. 创建一个新的，空的object -- new Object() <br /><br />b. 调用这个object的constructor;<br />   obj.construct也是一个对象,对象都具备prototype属性,这是不必说的. <br /><br />c. [补充] 拷贝这个object的construct的prototype属性到新生成的object中来(软拷贝引用) <br /><br />说明: 1) "new"关键字让一个普通函数变为了构造器，可以把它理解为一种用于简化创建对象步骤的"约定"<br />      2) 等价关系只能证明new的前两条作用，关于的prototype的叙述参见下边"2.3  prototype" <br /><br />---------------------------------------------------------------<br />2.3  prototype<br />---------------------------------------------------------------<br />1. 首先注意:<br />1) prototype是函数对象才具备的属性,普通对象是没有的．<br />　 -- 我对一些sb书上说它是一切对象的属性（因为它是Object对象的属性）感到困惑 <br /><br />2) 构造函数prototype属性本身也是一个object，它具有如下特征: <br /><br />   a. 它存在一个constructor属性指向函数对象的代码 (死规定，记住就ok), 例如： <br /><br />   　　　function showText(text) { alert(test);}<br />   　　　// 下面证明了showText的prototype属性是对象<br />         alert(typeof(showText.prototype));     // object<br />         // 下面说明了showText.prototype这个对象不能用默认toString()打印<br />         alert(showText.prototype);             // [object, Object]<br />         // 下面证明showText.prototype.constructor的存在性<br />         alert(showText.prototype.constructor); // function showText(text) { alert(test); }<br />         alert(typeof showText.prototype.constructor); // function <br /><br />   b. 它像其他对象一样可以添加属性，例如:<br />         // 添加属性text属性<br />         function showText() {};<br />         showText.prototype.text = "HelloWorld!~"; <br /><br />　　　　 // 添加shout()方法<br />         function showText() {}<br />         showText.prototype.shout = function(){alert("tomsui wants to smoke!~");}; <br /><br />2. prototype的内幕 <br /><br />　 回想new关键字的幕后机制:<br />　 先用构造器生成一个对象, 然后"软拷贝构造器prototype属性的内容到新生成的object中来"。<br />   下面，对引号中强调的内容有必要的两点解释: <br /><br />   1) "构造器prototype属性的内容"是什么?<br />       构造器prototype属性是一个对象，那么它的内容包括两部分: a. 属性值　b. 方法 <br /><br />   2) 什么是"软拷贝"?<br />      就是仅仅拷贝内容的引用到新生成obj,并不是真正的prototype中的内容(软拷贝是tomsui借用linux中"ln -s"的说法，比较简洁吧～) <br /><br />　 "软拷贝构造器prototype属性的内容到新生成的object中来"恐怕就是prototype的核心内幕了. <br /><br /><br />3. 引入prototype对javascript的影响 <br /><br />   1) 为创建对象添加附加动作<br />   　　　为构造器的prototype新添加的任何"属性"和"方法"，都会被new关键字在使用构造器创建对象时，附加到新的对象中去。<br />      　 例如： <br /><br />         function ShowText() {};<br />         // 添加text属性<br />         ShowText.prototype.text = "HelloWorld!~";<br />         alert(new ShowText().text);                   // HelloWorld!~ <br /><br />　　　　 // 添加shout()方法<br />         ShowText.prototype.shout = function(){alert("tomsui wants to smoke!~");};<br />         new ShowText().shout();                      // tomsui wants to smoke!~ <br /><br />　       上例中,构造器ShowText()本来可是没有text属性和shout()方法的哦～ <br /><br />　　2) prototype 不会影响到构造器的动作<br />　　　　所以如果两者发生矛盾时，构造器生效， -- 这非常值得注意！ <br /><br />　　　　例如:<br />        function ShowText()<br />        {<br />            this.text = "tomsui is handsome!~";<br />            this.say = function(){alert("absolutely!")};<br />        } <br /><br />        ShowText.prototype.text = "J.J. is handsome!~";<br />        ShowText.prototype.say = function(){alert("perhaps?")}; <br /><br />        var obj = new ShowText();<br />        alert(obj.text);　　　　　　　　　// tomsui is handsome!~<br />        obj.say();                        // absolutely! <br /><br />        结果是: prototype界定的"J.J. is handsome!~"没有生效，(毕竟是伪科学么);<br />                构造器讲出了"tomsui is handsome!~","absolutely!", 因为这是真理，不是prototype可以推翻的 <br /><br />　　3) prototype的出现，让js发生了所谓的"极晚绑定"。<br />　　　 晚绑定("后期绑定")可以参考TIJ或其他面向对象的书吧，不说了。<br />　　　"极晚绑定"让javascript的伪面向对象更加变态:即便已经new出了一个对象实例，你仍然可以为其添加新的行为和属性，<br />　　　 例如:<br />        function Person(name)<br />        {<br />            this.name = name;<br />            this.wordsInHeart = "tell Rora I love her~";<br />        }<br />        var tts = new Person("tomsui");　　// tell Rora I love her~<br />        alert(tts.wordsInHeart); <br /><br />        Person.prototype.saySomeOtherWords = function(){alert("tell Rora I need her~")};<br />        tts.saySomeOtherWords(); <br /><br />        看见没有:<br />        名为tomsui的Person对象出现时本来只会说"tell Rora I love her~"，<br />        但自从他学会了prototype招数，泡妞技术更上一层楼，<br />        于是补充他又会多说: "tell Rora I need her~"。 <br /><br />        这个例子可见"极晚绑定"的好处，有得有失，这种动作多了，你的js成本会很高(就是慢贝),所以谨慎使用。 <br /><br />ps.<br />I.   "极晚绑定"是官方用语，可放心使用; 不像"软拷贝"这词这土。<br />II.  并不是完整介绍js的伪面向对象，仅作为js做抛砖引玉用。<br />III.  再次声明，tomsui写在http://www.maycode.com上的,若转载请标明来源出处,joking的说，否则阴天下雨你server会down哦～　 : )
          <br/>
          <span style="color:red;">
            <a href="http://letle.javaeye.com/blog/200973#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 06 Jun 2008 15:38:16 +0800</pubDate>
        <link>http://letle.javaeye.com/blog/200973</link>
        <guid>http://letle.javaeye.com/blog/200973</guid>
      </item>
      <item>
        <title>浏览器兼容性</title>
        <author>letle</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://letle.javaeye.com">letle</a>&nbsp;
          链接：<a href="http://letle.javaeye.com/blog/184340" style="color:red;">http://letle.javaeye.com/blog/184340</a>&nbsp;
          发表时间: 2008年04月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          一、内核（浏览器引擎）<br />  IE：Trident（Windows平台）和Tasman（Mac平台）;其他像遨游，TT等IE内核的浏览器当然也是采用Trident。<br />  Firefox：Gecko,其他Netscape，Mozilla Thunderbird 也是采用它。<br />  Opera：Presto,(Kestrel)?<br />  Safari：Webkit（从KDE的KHTML及KJS引擎衍生而来）<br /><br />二、兼容性问题<br />  此处不多说类似于document.all的入门级问题了<br />  （一）.对于DOM的解释<br />  1.body<br />   IE：body完全解释完才存在<br />    Firefox：body一开始解释就存在<br />  2.iframe<br />   eg：&lt;iframe id="mF" name="mF" src=""about:blank">&lt;/iframe><br />  Firefox如果通过frames访问只能用iframe的name属性，或者用getElementById，但是前者是获取了frame潜入src文件的window对象，后者是获取到了当前document的一个HTMLIFrameElement对象<br />  IE，Firefox通过<strong>window</strong>.frames["mF"]都获取到了一个window对象<br />  但是Firefox还可以通过document.getElementById("mF").contentWindow来获取iframe潜入文档的window对象。<br />  3.document.write<br />  如果不使用document.open(),然后再write的方式，只要document被完全载入，IE和Firefox效果是一样的。但是write之前先open，write后没有close，那么在IE中后一次wirte的文本会把前一次write的文本冲掉，意思就是IE自动给close了，但是其他浏览器等于没有open一样。<br />  4.IE下input的type属性是只读的，其他常见的浏览器中是可以改写的。<br />  5.IE下无法用document.getElementsByName()来得到div，其他可以。<br />  6.IE对getAttribute("x")的返回值类型是根据setAttribute的时候赋值类型一样的。【Variant that returns a String, number, or Boolean value as defined by the attribute. 】<br />    而其他浏览器都是返回string。
          <br/>
          <span style="color:red;">
            <a href="http://letle.javaeye.com/blog/184340#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 19 Apr 2008 10:08:55 +0800</pubDate>
        <link>http://letle.javaeye.com/blog/184340</link>
        <guid>http://letle.javaeye.com/blog/184340</guid>
      </item>
      <item>
        <title>JVM详解之Java垃圾回收机制详解和调优 【转】</title>
        <author>letle</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://letle.javaeye.com">letle</a>&nbsp;
          链接：<a href="http://letle.javaeye.com/blog/170678" style="color:red;">http://letle.javaeye.com/blog/170678</a>&nbsp;
          发表时间: 2008年03月12日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>原地址：<a href="http://java.ccidnet.com/art/3539/20060314/476073_1.html">http://java.ccidnet.com/art/3539/20060314/476073_1.html</a> </p><table class="p11" cellspacing="0" border="0" width="560" cellpadding="0"><tbody><tr><td align="left" style="word-wrap: break-word"><span class="a14c"><p><strong><span style="font-size: 16px">1.JVM的gc概述</span></strong><br /><br />　　gc即垃圾收集机制是指jvm用于释放那些不再使用的对象所占用的内存。java语言并不要求jvm有gc，也没有规定gc如何工作。不过常用的jvm都有gc，而且大多数gc都使用类似的算法管理内存和执行收集操作。<br /><br />　　在充分理解了垃圾收集算法和执行过程后，才能有效的优化它的性能。有些垃圾收集专用于特殊的应用程序。比如，实时应用程序主要是为了避免垃圾收集中断，而大多数OLTP应用程序则注重整体效率。理解了应用程序的工作负荷和jvm支持的垃圾收集算法，便可以进行优化配置垃圾收集器。<br /><br />　　垃圾收集的目的在于清除不再使用的对象。gc通过确定对象是否被活动对象引用来确定是否收集该对象。gc首先要判断该对象是否是时候可以收集。两种常用的方法是引用计数和对象引用遍历。<br /><br />　　<strong>1.1.引用计数</strong><br /><br />　　引用计数存储对特定对象的所有引用数，也就是说，当应用程序创建引用以及引用超出范围时，jvm必须适当增减引用数。当某对象的引用数为0时，便可以进行垃圾收集。<br /><br />　　<strong>1.2.对象引用遍历</strong><br /><br />　　早期的jvm使用引用计数，现在大多数jvm采用对象引用遍历。对象引用遍历从一组对象开始，沿着整个对象图上的每条链接，递归确定可到达（reachable）的对象。如果某对象不能从这些根对象的一个（至少一个）到达，则将它作为垃圾收集。在对象遍历阶段，gc必须记住哪些对象可以到达，以便删除不可到达的对象，这称为标记（marking）对象。<br /><br />　　下一步，gc要删除不可到达的对象。删除时，有些gc只是简单的扫描堆栈，删除未标记的未标记的对象，并释放它们的内存以生成新的对象，这叫做清除（sweeping）。这种方法的问题在于内存会分成好多小段，而它们不足以用于新的对象，但是组合起来却很大。因此，许多gc可以重新组织内存中的对象，并进行压缩（compact），形成可利用的空间。<br /><br />　　为此，gc需要停止其他的活动活动。这种方法意味着所有与应用程序相关的工作停止，只有gc运行。结果，在响应期间增减了许多混杂请求。另外，更复杂的 gc不断增加或同时运行以减少或者清除应用程序的中断。有的gc使用单线程完成这项工作，有的则采用多线程以增加效率。<br /><br /><strong><span style="font-size: 16px">2.几种垃圾回收机制</span></strong><br /><br />　　<strong>2.1.标记－清除收集器</strong><br /><br />　　这种收集器首先遍历对象图并标记可到达的对象，然后扫描堆栈以寻找未标记对象并释放它们的内存。这种收集器一般使用单线程工作并停止其他操作。<br /><br />　　<strong>2.2.标记－压缩收集器</strong><br /><br />　　有时也叫标记－清除－压缩收集器，与标记－清除收集器有相同的标记阶段。在第二阶段，则把标记对象复制到堆栈的新域中以便压缩堆栈。这种收集器也停止其他操作。<br /><br />　　<strong>2.3.复制收集器</strong><br /><br />　　这种收集器将堆栈分为两个域，常称为半空间。每次仅使用一半的空间，jvm生成的新对象则放在另一半空间中。gc运行时，它把可到达对象复制到另一半空间，从而压缩了堆栈。这种方法适用于短生存期的对象，持续复制长生存期的对象则导致效率降低。<br /><br />　　<strong>2.4.增量收集器</strong><br /><br />　　增量收集器把堆栈分为多个域，每次仅从一个域收集垃圾。这会造成较小的应用程序中断。<br /><br />　　<strong>2.5.分代收集器</strong><br /><br />　　这种收集器把堆栈分为两个或多个域，用以存放不同寿命的对象。jvm生成的新对象一般放在其中的某个域中。过一段时间，继续存在的对象将获得使用期并转入更长寿命的域中。分代收集器对不同的域使用不同的算法以优化性能。<br /><br />　　<strong>2.6.并发收集器</strong><br /><br />　　并发收集器与应用程序同时运行。这些收集器在某点上（比如压缩时）一般都不得不停止其他操作以完成特定的任务，但是因为其他应用程序可进行其他的后台操作，所以中断其他处理的实际时间大大降低。<br /><br />　　<strong>2.7.并行收集器</strong><br /><br />　　并行收集器使用某种传统的算法并使用多线程并行的执行它们的工作。在多cpu机器上使用多线程技术可以显著的提高java应用程序的可扩展性。</p><p>&nbsp;</p><table class="p11" cellspacing="0" border="0" width="560" cellpadding="0"><tbody><tr><td align="left" style="word-wrap: break-word"><span class="a14c"><p style="text-indent: 2em">&nbsp;</p><p><strong><span style="font-size: 16px">3.Sun HotSpot</span></strong><br /><br />　　<strong>1.4.1 JVM堆大小的调整</strong><br /><br />　　Sun HotSpot 1.4.1使用分代收集器，它把堆分为三个主要的域：新域、旧域以及永久域。Jvm生成的所有新对象放在新域中。一旦对象经历了一定数量的垃圾收集循环后，便获得使用期并进入旧域。在永久域中jvm则存储class和method对象。就配置而言，永久域是一个独立域并且不认为是堆的一部分。<br /><br />　　下面介绍如何控制这些域的大小。可使用-Xms和-Xmx 控制整个堆的原始大小或最大值。<br /><br />　　下面的命令是把初始大小设置为128M：<br /><br />　　java &ndash;Xms128m<br /><br />　　&ndash;Xmx256m为控制新域的大小，可使用-XX:NewRatio设置新域在堆中所占的比例。<br /><br />　　下面的命令把整个堆设置成128m，新域比率设置成3，即新域与旧域比例为1：3，新域为堆的1/4或32M：<br /><br />java &ndash;Xms128m &ndash;Xmx128m<br />&ndash;XX:NewRatio =3可使用-XX:NewSize和-XX:MaxNewsize设置新域的初始值和最大值。<br /><br />　　下面的命令把新域的初始值和最大值设置成64m:<br /><br />java &ndash;Xms256m &ndash;Xmx256m &ndash;Xmn64m<br /><br />　　永久域默认大小为4m。运行程序时，jvm会调整永久域的大小以满足需要。每次调整时，jvm会对堆进行一次完全的垃圾收集。<br /><br />　　使用-XX:MaxPerSize标志来增加永久域搭大小。在WebLogic Server应用程序加载较多类时，经常需要增加永久域的最大值。当jvm加载类时，永久域中的对象急剧增加，从而使jvm不断调整永久域大小。为了避免调整，可使用-XX:PerSize标志设置初始值。<br /><br />　　下面把永久域初始值设置成32m，最大值设置成64m。<br /><br />java -Xms512m -Xmx512m -Xmn128m -XX:PermSize=32m -XX:MaxPermSize=64m<br /><br />　　默认状态下，HotSpot在新域中使用复制收集器。该域一般分为三个部分。第一部分为Eden，用于生成新的对象。另两部分称为救助空间，当Eden 充满时，收集器停止应用程序，把所有可到达对象复制到当前的from救助空间，一旦当前的from救助空间充满，收集器则把可到达对象复制到当前的to救助空间。From和to救助空间互换角色。维持活动的对象将在救助空间不断复制，直到它们获得使用期并转入旧域。使用-XX:SurvivorRatio 可控制新域子空间的大小。<br /><br />　　同NewRation一样，SurvivorRation规定某救助域与Eden空间的比值。比如，以下命令把新域设置成64m，Eden占32m，每个救助域各占16m：<br /><br />java -Xms256m -Xmx256m -Xmn64m -XX:SurvivorRation =2<br /><br />　　如前所述，默认状态下HotSpot对新域使用复制收集器，对旧域使用标记－清除－压缩收集器。在新域中使用复制收集器有很多意义，因为应用程序生成的大部分对象是短寿命的。理想状态下，所有过渡对象在移出Eden空间时将被收集。如果能够这样的话，并且移出Eden空间的对象是长寿命的，那么理论上可以立即把它们移进旧域，避免在救助空间反复复制。但是，应用程序不能适合这种理想状态，因为它们有一小部分中长寿命的对象。最好是保持这些中长寿命的对象并放在新域中，因为复制小部分的对象总比压缩旧域廉价。为控制新域中对象的复制，可用-XX:TargetSurvivorRatio控制救助空间的比例（该值是设置救助空间的使用比例。如救助空间位1M，该值50表示可用500K）。该值是一个百分比，默认值是50。当较大的堆栈使用较低的 sruvivorratio时，应增加该值到80至90，以更好利用救助空间。用-XX:maxtenuring threshold可控制上限。<br /><br />　　为放置所有的复制全部发生以及希望对象从eden扩展到旧域，可以把MaxTenuring Threshold设置成0。设置完成后，实际上就不再使用救助空间了，因此应把SurvivorRatio设成最大值以最大化Eden空间，设置如下：<br /><br />java &hellip; -XX:MaxTenuringThreshold=0 &ndash;XX:SurvivorRatio＝50000 &hellip;<br /><br /><strong><span style="font-size: 16px">4.BEA JRockit JVM的使用</span></strong><br /><br />　　Bea WebLogic 8.1使用的新的JVM用于Intel平台。在Bea安装完毕的目录下可以看到有一个类似于jrockit81sp1_141_03的文件夹。这就是 Bea新JVM所在目录。不同于HotSpot把Java字节码编译成本地码，它预先编译成类。JRockit还提供了更细致的功能用以观察JVM的运行状态，主要是独立的GUI控制台（只能适用于使用Jrockit才能使用jrockit81sp1_141_03自带的console监控一些cpu及 memory参数）或者WebLogic Server控制台。<br /><br />　　Bea JRockit JVM支持4种垃圾收集器：<br /><br />　　<strong>4.1.1.分代复制收集器</strong><br /><br />　　它与默认的分代收集器工作策略类似。对象在新域中分配，即JRockit文档中的nursery。这种收集器最适合单cpu机上小型堆操作。<br /><br />　　<strong>4.1.2.单空间并发收集器</strong><br /><br />　　该收集器使用完整堆，并与背景线程共同工作。尽管这种收集器可以消除中断，但是收集器需花费较长的时间寻找死对象，而且处理应用程序时收集器经常运行。如果处理器不能应付应用程序产生的垃圾，它会中断应用程序并关闭收集。<br /><br />　　分代并发收集器这种收集器在护理域使用排它复制收集器，在旧域中则使用并发收集器。由于它比单空间共同发生收集器中断频繁，因此它需要较少的内存，应用程序的运行效率也较高，注意，过小的护理域可以导致大量的临时对象被扩展到旧域中。这会造成收集器超负荷运作，甚至采用排它性工作方式完成收集。<br /><br />　　<strong>4.1.3.并行收集器</strong><br /><br />　　该收集器也停止其他进程的工作，但使用多线程以加速收集进程。尽管它比其他的收集器易于引起长时间的中断，但一般能更好的利用内存，程序效率也较高。<br /><br />　　默认状态下，JRockit使用分代并发收集器。要改变收集器，可使用-Xgc:，对应四个收集器分别为 gencopy，singlecon，gencon以及parallel。可使用-Xms和-Xmx设置堆的初始大小和最大值。要设置护理域，则使用- Xns:java &ndash;jrockit &ndash;Xms512m &ndash;Xmx512m &ndash;Xgc:gencon &ndash;Xns128m&hellip;尽管JRockit支持-verbose:gc开关，但它输出的信息会因收集器的不同而异。JRockit还支持memory、 load和codegen的输出。<br /><br />　　注意 ：如果 使用JRockit JVM的话还可以使用WLS自带的console（C:\bea\jrockit81sp1_141_03\bin下）来监控一些数据，如cpu， memery等。要想能构监控必须在启动服务时startWeblogic.cmd中加入－Xmanagement参数。</p></span></td></tr></tbody></table><p><strong><span style="font-size: 16px">5.如何从JVM中获取信息来进行调整</span><br /><br /></strong>　　-verbose.gc开关可显示gc的操作内容。打开它，可以显示最忙和最空闲收集行为发生的时间、收集前后的内存大小、收集需要的时间等。打开- xx:+ printgcdetails开关，可以详细了解gc中的变化。打开-XX: + PrintGCTimeStamps开关，可以了解这些垃圾收集发生的时间，自jvm启动以后以秒计量。最后，通过-xx: + PrintHeapAtGC开关了解堆的更详细的信息。为了了解新域的情况，可以通过-XX:=PrintTenuringDistribution开关了解获得使用期的对象权。<br /><br /><strong><span style="font-size: 16px">6.Pdm系统JVM调整</span></strong><br /><br />　<strong>　6.1.服务器：前提内存1G 单CPU</strong><br /><br />　　可通过如下参数进行调整：－server 启用服务器模式（如果CPU多，服务器机建议使用此项）<br /><br />　　－Xms,－Xmx一般设为同样大小。 800m<br /><br />　　－Xmn 是将NewSize与MaxNewSize设为一致。320m<br /><br />　　－XX:PerSize 64m<br /><br />　　－XX:NewSize 320m 此值设大可调大新对象区，减少Full GC次数<br /><br />　　－XX:MaxNewSize 320m<br /><br />　　－XX:NewRato NewSize设了可不设。<br /><br />　　－XX: SurvivorRatio<br /><br />　　－XX:userParNewGC 可用来设置并行收集<br /><br />　　－XX:ParallelGCThreads 可用来增加并行度<br /><br />　　－XXUseParallelGC 设置后可以使用并行清除收集器<br /><br />　　－XX：UseAdaptiveSizePolicy 与上面一个联合使用效果更好，利用它可以自动优化新域大小以及救助空间比值<br /><br />　　<strong>6.2.客户机：通过在JNLP文件中设置参数来调整客户端JVM</strong><br /><br />　　JNLP中参数：initial-heap-size和max-heap-size<br /><br />　　这可以在framework的RequestManager中生成JNLP文件时加入上述参数，但是这些值是要求根据客户机的硬件状态变化的（如客户机的内存大小等）。建议这两个参数值设为客户机可用内存的60％（有待测试）。为了在动态生成JNLP时以上两个参数值能够随客户机不同而不同，可靠虑获得客户机系统信息并将这些嵌到首页index.jsp中作为连接请求的参数。<br /><br />　　在设置了上述参数后可以通过Visualgc 来观察垃圾回收的一些参数状态，再做相应的调整来改善性能。一般的标准是减少fullgc的次数，最好硬件支持使用并行垃圾回收（要求多CPU）。 </p><p>&nbsp;</p><p>&nbsp;</p></span></td></tr></tbody></table><p>&nbsp;</p>
          <br/>
          <span style="color:red;">
            <a href="http://letle.javaeye.com/blog/170678#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 12 Mar 2008 23:14:18 +0800</pubDate>
        <link>http://letle.javaeye.com/blog/170678</link>
        <guid>http://letle.javaeye.com/blog/170678</guid>
      </item>
      <item>
        <title>全面分析Java的垃圾回收机制【转】</title>
        <author>letle</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://letle.javaeye.com">letle</a>&nbsp;
          链接：<a href="http://letle.javaeye.com/blog/170675" style="color:red;">http://letle.javaeye.com/blog/170675</a>&nbsp;
          发表时间: 2008年03月12日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          原帖地址：http://dev.yesky.com/178/2278678.shtml<br /><strong>引言 </strong><br /><br />　　Java的堆是一个运行时数据区，类的实例(对象)从中分配空间。Java虚拟机(JVM)的堆中储存着正在运行的应用程序所建立的所有对象，这些对象通过new、newarray、anewarray和multianewarray等指令建立，但是它们不需要程序代码来显式地释放。一般来说，堆的是由垃圾回收 来负责的，尽管JVM规范并不要求特殊的垃圾回收技术，甚至根本就不需要垃圾回收，但是由于内存的有限性，JVM在实现的时候都有一个由垃圾回收所管理的堆。垃圾回收是一种动态存储管理技术，它自动地释放不再被程序引用的对象，按照特定的垃圾收集算法来实现资源自动回收的功能。<br /><br />　　垃圾收集的意义<br /><br />　　在C++中，对象所占的内存在程序结束运行之前一直被占用，在明确释放之前不能分配给其它对象；而在Java中，当没有对象引用指向原先分配给某个对象的内存时，该内存便成为垃圾。JVM的一个系统级线程会自动释放该内存块。垃圾收集意味着程序不再需要的对象是"无用信息"，这些信息将被丢弃。当一个对象不再被引用的时候，内存回收它占领的空间，以便空间被后来的新对象使用。事实上，除了释放没用的对象，垃圾收集也可以清除内存记录碎片。由于创建对象和垃圾收集器释放丢弃对象所占的内存空间，内存会出现碎片。碎片是分配给对象的内存块之间的空闲内存洞。碎片整理将所占用的堆内存移到堆的一端，JVM将整理出的内存分配给新的对象。<br /><br />　　垃圾收集能自动释放内存空间，减轻编程的负担。这使Java 虚拟机具有一些优点。首先，它能使编程效率提高。在没有垃圾收集机制的时候，可能要花许多时间来解决一个难懂的存储器问题。在用Java语言编程的时候，靠垃圾收集机制可大大缩短时间。其次是它保护程序的完整性， 垃圾收集是Java语言安全性策略的一个重要部份。<br /><br />　　垃圾收集的一个潜在的缺点是它的开销影响程序性能。Java虚拟机必须追踪运行程序中有用的对象， 而且最终释放没用的对象。这一个过程需要花费处理器的时间。其次垃圾收集算法的不完备性，早先采用的某些垃圾收集算法就不能保证100%收集到所有的废弃内存。当然随着垃圾收集算法的不断改进以及软硬件运行效率的不断提升，这些问题都可以迎刃而解。<br /><br />　　垃圾收集的算法分析<br /><br />　　Java语言规范没有明确地说明JVM使用哪种垃圾回收算法，但是任何一种垃圾收集算法一般要做2件基本的事情：（1）发现无用信息对象；（2）回收被无用对象占用的内存空间，使该空间可被程序再次使用。<br /><br />　　大多数垃圾回收算法使用了根集(root set)这个概念；所谓根集就量正在执行的Java程序可以访问的引用变量的集合(包括局部变量、参数、类变量)，程序可以使用引用变量访问对象的属性和调用对象的方法。垃圾收集首选需要确定从根开始哪些是可达的和哪些是不可达的，从根集可达的对象都是活动对象，它们不能作为垃圾被回收，这也包括从根集间接可达的对象。而根集通过任意路径不可达的对象符合垃圾收集的条件，应该被回收。下面介绍几个常用的算法。<br /><br />　　1、 引用计数法(Reference Counting Collector)<br /><br />　　引用计数法是唯一没有使用根集的垃圾回收的法，该算法使用引用计数器来区分存活对象和不再使用的对象。一般来说，堆中的每个对象对应一个引用计数器。当每一次创建一个对象并赋给一个变量时，引用计数器置为1。当对象被赋给任意变量时，引用计数器每次加1当对象出了作用域后(该对象丢弃不再使用)，引用计数器减1，一旦引用计数器为0，对象就满足了垃圾收集的条件。<br /><br />　　基于引用计数器的垃圾收集器运行较快，不会长时间中断程序执行，适宜地必须 实时运行的程序。但引用计数器增加了程序执行的开销，因为每次对象赋给新的变量，计数器加1，而每次现有对象出了作用域生，计数器减1。<br /><br />　　2、tracing算法(Tracing Collector)<br /><br />　　tracing算法是为了解决引用计数法的问题而提出，它使用了根集的概念。基于tracing算法的垃圾收集器从根集开始扫描，识别出哪些对象可达，哪些对象不可达，并用某种方式标记可达对象，例如对每个可达对象设置一个或多个位。在扫描识别过程中，基于tracing算法的垃圾收集也称为标记和清除(mark-and-sweep)垃圾收集器.<br /><br />　　3、compacting算法(Compacting Collector)<br /><br />　　为了解决堆碎片问题，基于tracing的垃圾回收吸收了Compacting算法的思想，在清除的过程中，算法将所有的对象移到堆的一端，堆的另一端就变成了一个相邻的空闲内存区，收集器会对它移动的所有对象的所有引用进行更新，使得这些引用在新的位置能识别原来 的对象。在基于Compacting算法的收集器的实现中，一般增加句柄和句柄表。　　<br /><br />　　4、copying算法(Coping Collector)<br /><br />　　该算法的提出是为了克服句柄的开销和解决堆碎片的垃圾回收。它开始时把堆分成 一个对象 面和多个空闲面， 程序从对象面为对象分配空间，当对象满了，基于coping算法的垃圾 收集就从根集中扫描活动对象，并将每个 活动对象复制到空闲面(使得活动对象所占的内存之间没有空闲洞)，这样空闲面变成了对象面，原来的对象面变成了空闲面，程序会在新的对象面中分配内存。<br /><br />　　一种典型的基于coping算法的垃圾回收是stop-and-copy算法，它将堆分成对象面和空闲区域面，在对象面与空闲区域面的切换过程中，程序暂停执行。<br /><br />　　5、generation算法(Generational Collector)<br /><br />　　stop-and-copy垃圾收集器的一个缺陷是收集器必须复制所有的活动对象，这增加了程序等待时间，这是coping算法低效的原因。在程序设计中有这样的规律：多数对象存在的时间比较短，少数的存在时间比较长。因此，generation算法将堆分成两个或多个，每个子堆作为对象的一代(generation)。由于多数对象存在的时间比较短，随着程序丢弃不使用的对象，垃圾收集器将从最年轻的子堆中收集这些对象。在分代式的垃圾收集器运行后，上次运行存活下来的对象移到下一最高代的子堆中，由于老一代的子堆不会经常被回收，因而节省了时间。<br /><br />　　6、adaptive算法(Adaptive Collector)<br /><br />　　在特定的情况下，一些垃圾收集算法会优于其它算法。基于Adaptive算法的垃圾收集器就是监控当前堆的使用情况，并将选择适当算法的垃圾收集器。<br /><br /><strong>透视Java垃圾回收</strong><br /><br />　　1、命令行参数透视垃圾收集器的运行<br /><br />　　2、使用System.gc()可以不管JVM使用的是哪一种垃圾回收的算法，都可以请求Java的垃圾回收。在命令行中有一个参数-verbosegc可以查看Java使用的堆内存的情况，它的格式如下：<br /><br />java -verbosegc classfile<br /><br />　　可以看个例子：<br /><br />class TestGC <br />{<br />　public static void main(String[] args) <br />　{<br />　　new TestGC();<br />　　System.gc();<br />　　System.runFinalization();<br />　}<br />} <br /><br />　　在这个例子中，一个新的对象被创建，由于它没有使用，所以该对象迅速地变为可达，程序编译后，执行命令： java -verbosegc TestGC 后结果为：<br /><br />[Full GC 168K->97K(1984K)， 0.0253873 secs]<br /><br />　　机器的环境为，Windows 2000 + JDK1.3.1，箭头前后的数据168K和97K分别表示垃圾收集GC前后所有存活对象使用的内存容量，说明有168K-97K=71K的对象容量被回收，括号内的数据1984K为堆内存的总容量，收集所需要的时间是0.0253873秒（这个时间在每次执行的时候会有所不同）。<br /><br />　　2、finalize方法透视垃圾收集器的运行<br /><br />　　在JVM垃圾收集器收集一个对象之前 ，一般要求程序调用适当的方法释放资源，但在没有明确释放资源的情况下，Java提供了缺省机制来终止化该对象心释放资源，这个方法就是finalize（）。它的原型为：<br /><br />protected void finalize() throws Throwable <br /><br />　　在finalize()方法返回之后，对象消失，垃圾收集开始执行。原型中的throws Throwable表示它可以抛出任何类型的异常。<br /><br />　　之所以要使用finalize()，是由于有时需要采取与Java的普通方法不同的一种方法，通过分配内存来做一些具有C风格的事情。这主要可以通过"固有方法"来进行，它是从Java里调用非Java方法的一种方式。C和C++是目前唯一获得固有方法支持的语言。但由于它们能调用通过其他语言编写的子程序，所以能够有效地调用任何东西。在非Java代码内部，也许能调用C的malloc()系列函数，用它分配存储空间。而且除非调用了free()，否则存储空间不会得到释放，从而造成内存"漏洞"的出现。当然，free()是一个C和C++函数，所以我们需要在finalize()内部的一个固有方法中调用它。也就是说我们不能过多地使用finalize()，它并不是进行普通清除工作的理想场所。<br /><br />　　在普通的清除工作中，为清除一个对象，那个对象的用户必须在希望进行清除的地点调用一个清除方法。这与C++"破坏器"的概念稍有抵触。在C++中，所有对象都会破坏（清除）。或者换句话说，所有对象都"应该"破坏。若将C++对象创建成一个本地对象，比如在堆栈中创建（在Java中是不可能的），那么清除或破坏工作就会在"结束花括号"所代表的、创建这个对象的作用域的末尾进行。若对象是用new创建的（类似于Java），那么当程序员调用C++的delete命令时（Java没有这个命令），就会调用相应的破坏器。若程序员忘记了，那么永远不会调用破坏器，我们最终得到的将是一个内存"漏洞"，另外还包括对象的其他部分永远不会得到清除。<br /><br />　　相反，Java不允许我们创建本地（局部）对象--无论如何都要使用new。但在Java中，没有"delete"命令来释放对象，因为垃圾收集器会帮助我们自动释放存储空间。所以如果站在比较简化的立场，我们可以说正是由于存在垃圾收集机制，所以Java没有破坏器。然而，随着以后学习的深入，就会知道垃圾收集器的存在并不能完全消除对破坏器的需要，或者说不能消除对破坏器代表的那种机制的需要（而且绝对不能直接调用finalize()，所以应尽量避免用它）。若希望执行除释放存储空间之外的其他某种形式的清除工作，仍然必须调用Java中的一个方法。它等价于C++的破坏器，只是没后者方便。<br /><br />　　下面这个例子向大家展示了垃圾收集所经历的过程，并对前面的陈述进行了总结。<br /><br />class Chair {<br />　static boolean gcrun = false;<br />　static boolean f = false;<br />　static int created = 0;<br />　static int finalized = 0;<br />　int i;<br />　Chair() {<br />　　i = ++created;<br />　　if(created == 47) <br />　　　System.out.println("Created 47");<br />　}<br />　protected void finalize() {<br />　　if(!gcrun) {<br />　　　gcrun = true;<br />　　　System.out.println("Beginning to finalize after " + created + " Chairs have been created");<br />　　}<br />　　if(i == 47) {<br />　　　System.out.println("Finalizing Chair #47， " +"Setting flag to stop Chair creation");<br />　　　f = true;<br />　　}<br />　　finalized++;<br />　　if(finalized >= created)<br />　　　System.out.println("All " + finalized + " finalized");<br />　}<br />}<br /><br />public class Garbage {<br />　public static void main(String[] args) {<br />　　if(args.length == 0) {<br />　　　System.err.println("Usage: \n" + "java Garbage before\n or:\n" + "java Garbage after");<br />　　　return;<br />　　}<br />　　while(!Chair.f) {<br />　　　new Chair();<br />　　　new String("To take up space");<br />　　}<br />　　System.out.println("After all Chairs have been created:\n" + "total created = " + Chair.created +<br />"， total finalized = " + Chair.finalized);<br />　　if(args[0].equals("before")) {<br />　　　　System.out.println("gc():");<br />　　　　System.gc();<br />　　　　System.out.println("runFinalization():");<br />　　　　System.runFinalization();<br />　　}<br />　　System.out.println("bye!");<br />　　if(args[0].equals("after"))<br />　　　System.runFinalizersOnExit(true);<br />　}<br />} <br /><br />　　上面这个程序创建了许多Chair对象，而且在垃圾收集器开始运行后的某些时候，程序会停止创建Chair。由于垃圾收集器可能在任何时间运行，所以我们不能准确知道它在何时启动。因此，程序用一个名为gcrun的标记来指出垃圾收集器是否已经开始运行。利用第二个标记f，Chair可告诉main()它应停止对象的生成。这两个标记都是在finalize()内部设置的，它调用于垃圾收集期间。另两个static变量--created以及finalized--分别用于跟踪已创建的对象数量以及垃圾收集器已进行完收尾工作的对象数量。最后，每个Chair都有它自己的（非static）int i，所以能跟踪了解它具体的编号是多少。编号为47的Chair进行完收尾工作后，标记会设为true，最终结束Chair对象的创建过程。<br /><br /><strong>关于垃圾收集的几点补充</strong><br /><br />　　经过上述的说明，可以发现垃圾回收有以下的几个特点：<br /><br />　　（1）垃圾收集发生的不可预知性：由于实现了不同的垃圾收集算法和采用了不同的收集机制，所以它有可能是定时发生，有可能是当出现系统空闲CPU资源时发生，也有可能是和原始的垃圾收集一样，等到内存消耗出现极限时发生，这与垃圾收集器的选择和具体的设置都有关系。<br /><br />　　（2）垃圾收集的精确性：主要包括2 个方面：（a）垃圾收集器能够精确标记活着的对象；（b）垃圾收集器能够精确地定位对象之间的引用关系。前者是完全地回收所有废弃对象的前提，否则就可能造成内存泄漏。而后者则是实现归并和复制等算法的必要条件。所有不可达对象都能够可靠地得到回收，所有对象都能够重新分配，允许对象的复制和对象内存的缩并，这样就有效地防止内存的支离破碎。<br /><br />　　（3）现在有许多种不同的垃圾收集器，每种有其算法且其表现各异，既有当垃圾收集开始时就停止应用程序的运行，又有当垃圾收集开始时也允许应用程序的线程运行，还有在同一时间垃圾收集多线程运行。<br /><br />　　（4）垃圾收集的实现和具体的JVM 以及JVM的内存模型有非常紧密的关系。不同的JVM 可能采用不同的垃圾收集，而JVM 的内存模型决定着该JVM可以采用哪些类型垃圾收集。现在，HotSpot 系列JVM中的内存系统都采用先进的面向对象的框架设计，这使得该系列JVM都可以采用最先进的垃圾收集。<br /><br />　　（5）随着技术的发展，现代垃圾收集技术提供许多可选的垃圾收集器，而且在配置每种收集器的时候又可以设置不同的参数，这就使得根据不同的应用环境获得最优的应用性能成为可能。<br /><br />　　针对以上特点，我们在使用的时候要注意：<br /><br />　　（1）不要试图去假定垃圾收集发生的时间，这一切都是未知的。比如，方法中的一个临时对象在方法调用完毕后就变成了无用对象，这个时候它的内存就可以被释放。<br /><br />　　（2）Java中提供了一些和垃圾收集打交道的类，而且提供了一种强行执行垃圾收集的方法--调用System.gc()，但这同样是个不确定的方法。Java 中并不保证每次调用该方法就一定能够启动垃圾收集，它只不过会向JVM发出这样一个申请，到底是否真正执行垃圾收集，一切都是个未知数。<br /><br />　　（3）挑选适合自己的垃圾收集器。一般来说，如果系统没有特殊和苛刻的性能要求，可以采用JVM的缺省选项。否则可以考虑使用有针对性的垃圾收集器，比如增量收集器就比较适合实时性要求较高的系统之中。系统具有较高的配置，有比较多的闲置资源，可以考虑使用并行标记/清除收集器。<br /><br />　　（4）关键的也是难把握的问题是内存泄漏。良好的编程习惯和严谨的编程态度永远是最重要的，不要让自己的一个小错误导致内存出现大漏洞。<br /><br />　　（5）尽早释放无用对象的引用。大多数程序员在使用临时变量的时候，都是让引用变量在退出活动域(scope)后，自动设置为null，暗示垃圾收集器来收集该对象，还必须注意该引用的对象是否被监听，如果有，则要去掉监听器，然后再赋空值。<br /><br />　　结束语<br /><br />　　一般来说，Java开发人员可以不重视JVM中堆内存的分配和垃圾处理收集，但是，充分理解Java的这一特性可以让我们更有效地利用资源。同时要注意finalize()方法是Java的缺省机制，有时为确保对象资源的明确释放，可以编写自己的finalize方法。
          <br/>
          <span style="color:red;">
            <a href="http://letle.javaeye.com/blog/170675#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 12 Mar 2008 23:12:13 +0800</pubDate>
        <link>http://letle.javaeye.com/blog/170675</link>
        <guid>http://letle.javaeye.com/blog/170675</guid>
      </item>
      <item>
        <title>CMD命令大全及详细解释和语法</title>
        <author>letle</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://letle.javaeye.com">letle</a>&nbsp;
          链接：<a href="http://letle.javaeye.com/blog/169045" style="color:red;">http://letle.javaeye.com/blog/169045</a>&nbsp;
          发表时间: 2008年03月07日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          CMD命令大全及详细解释和语法<br />Microsoft Windows XP [版本 5.1.2600]<br /><br />有关某个命令的详细信息，请键入 HELP 命令名<br /><br />ASSOC    显示或修改文件扩展名关联。<br />AT       计划在计算机上运行的命令和程序。<br />ATTRIB   显示或更改文件属性。<br />BREAK    设置或清除扩展式 CTRL+C 检查。<br />CACLS    显示或修改文件的访问控制列表(ACLs)。<br />CALL     从另一个批处理程序调用这一个。<br />CD       显示当前目录的名称或将其更改。<br />CHCP     显示或设置活动代码页数。<br />CHDIR    显示当前目录的名称或将其更改。<br />CHKDSK   检查磁盘并显示状态报告。<br />CHKNTFS  显示或修改启动时间磁盘检查。<br />CLS      清除屏幕。<br />CMD      打开另一个 Windows 命令解释程序窗口。<br />COLOR    设置默认控制台前景和背景颜色。<br />COMP     比较两个或两套文件的内容。<br />COMPACT  显示或更改 NTFS 分区上文件的压缩。<br />CONVERT  将 FAT 卷转换成 NTFS。您不能转换当前驱动器。<br />COPY     将至少一个文件复制到另一个位置。<br />DATE     显示或设置日期。<br />DEL      删除至少一个文件。<br />DIR      显示一个目录中的文件和子目录。<br />DISKCOMP 比较两个软盘的内容。<br />DISKCOPY 将一个软盘的内容复制到另一个软盘。<br />DOSKEY   编辑命令行、调用 Windows 命令并创建宏。<br />ECHO     显示消息，或将命令回显打开或关上。<br />ENDLOCAL 结束批文件中环境更改的本地化。<br />ERASE    删除至少一个文件。<br />EXIT     退出 CMD.EXE 程序(命令解释程序)。<br />FC       比较两个或两套文件，并显示不同处。<br />FIND     在文件中搜索文字字符串。<br />FINDSTR  在文件中搜索字符串。<br />FOR      为一套文件中的每个文件运行一个指定的命令。<br />FORMAT   格式化磁盘，以便跟 Windows 使用。<br />FTYPE    显示或修改用于文件扩展名关联的文件类型。<br />GOTO     将 Windows 命令解释程序指向批处理程序中某个标明的行。<br />GRAFTABL 启用 Windows 来以图像模式显示扩展字符集。<br />HELP     提供 Windows 命令的帮助信息。<br />IF       执行批处理程序中的条件性处理。<br />LABEL    创建、更改或删除磁盘的卷标。<br />MD       创建目录。<br />MKDIR    创建目录。<br />MODE     配置系统设备。<br />MORE     一次显示一个结果屏幕。<br />MOVE     将文件从一个目录移到另一个目录。<br />PATH     显示或设置可执行文件的搜索路径。<br />PAUSE    暂停批文件的处理并显示消息。<br />POPD     还原 PUSHD 保存的当前目录的上一个值。<br />PRINT    打印文本文件。<br />PROMPT   更改 Windows 命令提示符。<br />PUSHD    保存当前目录，然后对其进行更改。<br />RD       删除目录。<br />RECOVER  从有问题的磁盘恢复可读信息。<br />REM      记录批文件或 CONFIG.SYS 中的注释。<br />REN      重命名文件。<br />RENAME   重命名文件。<br />REPLACE  替换文件。<br />RMDIR    删除目录。<br />SET      显示、设置或删除 Windows 环境变量。<br />SETLOCAL 开始批文件中环境更改的本地化。<br />SHIFT    更换批文件中可替换参数的位置。<br />SORT     对输入进行分类。<br />START    启动另一个窗口来运行指定的程序或命令。<br />SUBST    将路径跟一个驱动器号关联。<br />TIME     显示或设置系统时间。<br />TITLE    设置 CMD.EXE 会话的窗口标题。<br />TREE     以图形模式显示驱动器或路径的目录结构。<br />TYPE     显示文本文件的内容。<br />VER      显示 Windows 版本。<br />VERIFY   告诉 Windows 是否验证文件是否已正确写入磁盘。<br />VOL      显示磁盘卷标和序列号。<br />XCOPY    复制文件和目录树。<br /><br />***************<br /><br /><strong>以下是每个命令的详细解释及用法</strong><br /><br />***************<br /><br />显示或修改文件扩展名关联<br /><br />ASSOC [.ext[=[fileType]]]<br /><br />  .ext      指定跟文件类型关联的文件扩展名<br />  fileType  指定跟文件扩展名关联的文件类型<br /><br />键入 ASSOC 而不带参数，显示当前文件关联。如果只用文件扩展名调用 ASSOC，则显示那个文件扩展名的当前文件关联。如果不为文件类型指定任何参数，命令会删除文件扩展名的关联。<br /><br />***************<br /><br />AT 命令安排在特定日期和时间运行命令和程序。<br />要使用 AT 命令，计划服务必须已在运行中。<br />                                                           <br />AT [\\computername] [ [id] [/DELETE] | /DELETE [/YES]]                    <br />AT [\\computername] time [/INTERACTIVE] [ /EVERY:date[,...] | /NEXT:date[,...]] "command"<br /><br />\\computername       指定远程计算机。 如果省略这个参数，会计划在本地计算机上运行命令。             <br />id                   指定给已计划命令的识别号。<br />/delete              删除某个已计划的命令。如果省略 id，计算机上所有已计划的命令都会被删除。<br />/yes                 不需要进一步确认时，跟删除所有作业的命令一起使用。<br />time                 指定运行命令的时间。<br />/interactive         允许作业在运行时，与当时登录的用户桌面进行交互。<br />/every:date[,...]    每个月或每个星期在指定的日期运行命令。如果省略日期，则默认为在每月的本日运行。<br />/next:date[,...]     指定在下一个指定日期(如，下周四)运行命令。如果省略日期，则默认为在每月的本日运行。<br />"command"            准备运行的 Windows NT 命令或批处理程序。<br /><br />***************<br /><br />显示或更改文件属性。<br /><br />ATTRIB [+R | -R] [+A | -A ] [+S | -S] [+H | -H] [[drive:] [path] filename] [/S [/D]]<br /><br />  +   设置属性。<br />  -    清除属性。<br />  R   只读文件属性。<br />  A   存档文件属性。<br />  S   系统文件属性。<br />  H   隐藏文件属性。<br />  [drive:][path][filename]<br />      指定要处理的文件属性。<br />  /S  处理当前文件夹及其子文件夹中的匹配文件。<br />  /D  也处理文件夹。<br /><br />***************<br /><br />设置或清除 DOS 系统的扩展 CTRL+C 检测<br /><br />这个命令是为了与 DOS 系统的兼容而保留的，在 Windows XP 里不起作用。<br /><br />如果命令扩展名被启用，并且操作平台是 Windows XP，BREAK 命令会在被调试程序调试时输入一个硬代码中断点。<br /><br />***************<br /><br />显示或者修改文件的访问控制表(ACL)CACLS filename [/T] [/E] [/C] [/G user:perm] [/R user [...]]               [/P user:perm [...]] [/D user [...]]   filename      显示 ACL。   /T            更改当前目录及其所有子目录中指定文件的 ACL。   /E            编辑 ACL 而不替换。   /C            在出现拒绝访问错误时继续。   /G user:perm  赋予指定用户访问权限。                 Perm 可以是: R  读取                              W  写入                               C  更改(写入)                              F  完全控制   /R user         撤销指定用户的访问权限(仅在与 /E 一起使用时合法)。   /P user:perm  替换指定用户的访问权限。                 Perm 可以是: N  无                              R  读取                              W  写入                              C  更改(写入)                              F  完全控制   /D user       拒绝指定用户的访问。在命令中可以使用通配符指定多个文件。也可以在命令中指定多个用户。缩写:   CI - 容器继承。        ACE 会由目录继承。   OI - 对象继承。        ACE 会由文件继承。   IO - 只继承。        ACE 不适用于当前文件/目录。<br /><br />***************<br />从批处理程序调用另一个批处理程序。<br /><br />CALL [drive:][path]filename [batch-parameters]<br /><br />  batch-parameters   指定批处理程序所需的命令行信息。<br /><br />如果命令扩展名被启用，CALL 会如下改变:<br /><br />CALL 命令现在将卷标当作 CALL 的目标接受。语法是:<br /><br />    CALL:label arguments<br /><br />一个新的批文件上下文由指定的参数所创建，控制在卷标被指定后传递到语句。您必须通过达到批脚本文件末两次来 "exit" 两次。第一次读到文件末时，控制会回到 CALL 语句的紧后面。第二次会退出批脚本。键入 GOTO /?，参看 GOTO  : EOF  扩展名的描述，此描述允许您从一个批脚本返回。<br /><br />另外，批脚本文本参数参照(%0、%1、等等)已如下改变:<br /><br />     批脚本里的 %* 指出所有的参数(如 %1 %2 %3 %4 %5 ...)<br /><br />     批参数(%n)的替代已被增强。您可以使用以下语法:<br /><br />         %~1         - 删除引号(")，扩充 %1<br />         %~f1        - 将 %1 扩充到一个完全合格的路径名<br />         %~d1        - 仅将 %1 扩充到一个驱动器号<br />         %~p1        - 仅将 %1 扩充到一个路径<br />         %~n1        - 仅将 %1 扩充到一个文件名<br />         %~x1        - 仅将 %1 扩充到一个文件扩展名<br />         %~s1        - 扩充的路径指含有短名<br />         %~a1        - 将 %1 扩充到文件属性<br />         %~t1        - 将 %1 扩充到文件的日期/时间<br />         %~z1        - 将 %1 扩充到文件的大小<br />         %~$PATH : 1 - 查找列在 PATH 环境变量的目录，并将 %1 扩充到找到的第一个完全合格的名称。如果环境变量名未被定义，或者没有找到文件，此组合键会扩充到空字符串<br /><br />    可以组合修定符来取得多重结果:<br /><br />        %~dp1       - 只将 %1 扩展到驱动器号和路径<br />        %~nx1       - 只将 %1 扩展到文件名和扩展名<br />        %~dp$PATH:1 - 在列在 PATH 环境变量中的目录里查找 %1，并扩展到找到的第一个文件的驱动器号和路径。<br />        %~ftza1     - 将 %1 扩展到类似 DIR 的输出行。<br /><br />    在上面的例子中，%1 和 PATH 可以被其他有效数值替换。 %~ 语法被一个有效参数号码终止。%~ 修定符不能跟 %* 使用<br /><br />***************<br /><br />显示当前目录名或改变当前目录。<br /><br />CHDIR [/D] [drive:][path]<br />CHDIR [..]<br />CD [/D] [drive:][path]<br />CD [..]<br /><br />  ..   指定要改成父目录。<br /><br />键入 CD 驱动器: 显示指定驱动器中的当前目录。<br />不带参数只键入 CD，则显示当前驱动器和目录。<br /><br />使用 /D 命令行开关，除了改变驱动器的当前目录之外，还可改变当前驱动器。<br /><br />如果扩展命令名被启用，CHDIR 会如下改变:<br /><br />当前的目录字符串会被转换成使用磁盘名上的大小写。所以，如果磁盘上的大小写如此，CD  C : \TEMP 会将当前目录设为 C:\Temp。<br /><br />CHDIR 命令不把空格当作分隔符，因此有可能将目录名改为一个带有空格但不带有引号的子目录名。例如:<br /><br />     cd \winnt\profiles\username\programs\start menu<br /><br />与下列相同:  <br /><br />     cd "\winnt\profiles\username\programs\start menu" <br /><br />在扩展功能停用的情况下，您必须键入以上命令。<br /><br />***************<br /><br />显示或设置活动代码页编号。<br /><br />CHCP [nnn]<br /><br />  nnn   指定代码页编号。<br /><br />不加参数键入 CHCP 显示活动代码页编号。<br /><br />***************<br /><br />显示当前目录名或改变当前目录。<br /><br />CHDIR [/D] [drive:][path]<br />CHDIR [..]<br />CD [/D] [drive:][path]<br />CD [..]<br /><br />  ..   指定要改成父目录。<br /><br />键入 CD 驱动器: 显示指定驱动器中的当前目录。<br />不带参数只键入 CD，则显示当前驱动器和目录。<br /><br />使用 /D 命令行开关，除了改变驱动器的当前目录之外，还可改变当前驱动器。<br /><br />如果扩展命令名被启用，CHDIR 会如下改变:<br /><br />当前的目录字符串会被转换成使用磁盘名上的大小写。所以，如果磁盘上的大小写如此，CD  C : \TEMP 会将当前目录设为 C:\Temp。<br /><br />CHDIR 命令不把空格当作分隔符，因此有可能将目录名改为一个带有空格但不带有引号的子目录名。例如:<br /><br />     cd \winnt\profiles\username\programs\start menu<br /><br />与下列相同:  <br /><br />     cd "\winnt\profiles\username\programs\start menu" <br /><br />在扩展功能停用的情况下，您必须键入以上命令。<br /><br />***************<br /><br />检查磁盘并显示状态报告。<br /><br />CHKDSK [volume[[path]filename]]] [/F] [/V] [/R] [/X] [/I] [/C] [/L[:size]]<br /><br />  volume          指定驱动器(后面跟一个冒号)、装入点或卷名。<br />  filename        仅用于 FAT/FAT32: 指定要检查是否有碎片的文件。<br />  /F              修复磁盘上的错误。<br />  /V              在 FAT/FAT32 上: 显示磁盘上每个文件的完整路径和名称。在 NTFS 上: 如果有清除消息，将其显示。<br />  /R              查找不正确的扇区并恢复可读信息(隐含 /F)。<br />  /L:size       仅用于 NTFS:  将日志文件大小改成指定的 KB 数。如果没有指定大小，则显示当前的大小。<br />  /X              如果必要，强制卷先卸下。卷的所有打开的句柄就会无效(隐含 /F)。<br />  /I              仅用于 NTFS: 对索引项进行强度较小的检查。<br />  /C              仅用于 NTFS: 跳过文件夹结构的循环检查。<br /><br />/I 和 /C 命令行开关跳过卷的某些检查，减少运行 Chkdsk 所需的时间。<br /><br />***************<br /><br />在启动时显示或修改磁盘检查。<br /><br />CHKNTFS volume [...]<br />CHKNTFS /D<br />CHKNTFS /T[:time]\r\nCHKNTFS /X volume [...]<br />CHKNTFS /C volume [...]<br /><br />  volume:        指定驱动器(后面跟一个冒号)、装入点或卷名。<br />  /D             将计算机恢复成默认状态， 启动时检查所有驱动器，并对有问题的驱动器执行 chkdsk 命令。<br />  /T:time        将 AUTOCHK 初始递减计数时间改成指定的时间量，单位为秒数。如果没有指定时间，则显示当前设置。<br />  /X             排除启动时不作检查的驱动器。上次执行此命令排除的驱动器此时无效。<br />  /C             安排启动时检查驱动器，如果驱动器有问题，运行 chkdsk。<br /><br />如果没有指定命令行开关，CHKNTFS 会显示每一驱动器有问题的位的状态。<br /><br />***************<br /><br />清除屏幕。<br /><br />CLS<br /><br />***************<br /><br />启动 Windows XP 命令解释程序一个新的实例<br /><br />CMD [/A | /U] [/Q] [/D] [/E:ON | /E:OFF] [/F:ON | /F:OFF] [/V:ON | /V:OFF]<br />    [[/S] [/C | /K] string]<br /><br />/C      执行字符串指定的命令然后终断<br />/K      执行字符串指定的命令但保留<br />/S      在 /C 或 /K 后修改字符串处理(见下)<br />/Q      关闭回应<br />/D      从注册表中停用执行 AutoRun 命令(见下)<br />/A      使向内部管道或文件命令的输出成为 ANSI<br />/U      使向内部管道或文件命令的输出成为 Unicode<br />/T:fg   设置前景/背景颜色(详细信息，请见 COLOR /?)<br />/E:ON   启用命令扩展(见下)<br />/E:OFF  停用命令扩展(见下)<br />/F:ON   启用文件和目录名称完成字符 (见下)<br />/F:OFF  停用文件和目录名称完成字符(见下)<br />/V:ON   将 ! 作为定界符启动延缓环境变量扩展。如: /V:ON 会允许 !var! 在执行时允许 !var! 扩展变量 var。var 语法在输入时扩展变量，这与在一个 FOR 循环内不同。<br />/V:OFF  停用延缓的环境扩展。<br /><br />请注意，如果字符串有引号，可以接受用命令分隔符 '&&' 隔开的多个命令。并且，由于兼容原因，/X 与 /E:ON 相同，/Y 与 /E:OFF 相同，并且 /R 与 /C 相同。忽略任何其他命令行开关。<br /><br />如果指定了 /C 或 /K，命令行开关后的命令行其余部分将作为命令行处理；在这种情况下，会使用下列逻辑处理引号字符("):<br /><br />    1.   如果符合下列所有条件，那么在命令行上的引号字符将被保留:<br /><br />        - 不带 /S 命令行开关<br />        - 整整两个引号字符<br />        - 在两个引号字符之间没有特殊字符，特殊字符为下列中的一个: &lt;>()@^|<br />        - 在两个引号字符之间有至少一个空白字符<br />        - 在两个引号字符之间有至少一个可执行文件的名称。<br /><br />    2.  否则，老办法是，看第一个字符是否是一个引号字符，如果是，舍去开头的字符并删除命令行上 的最后一个引号字符，保留最后一个引号字符之后的文字。<br /><br />如果 /D 未在命令行上被指定，当 CMD.EXE 开始时，它会寻找以下 REG_SZ/REG_EXPAND_SZ 注册表变量。如果其中一个或两个都存在，这两个变量会先被执行。<br /><br />    HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\AutoRun<br /><br />        和/或<br /><br />    HKEY_CURRENT_USER\Software\Microsoft\Command Processor\AutoRun<br /><br />命令扩展是按默认值启用的。您也可以使用 /E:OFF，为某一特定调用而停用扩展。您可以在机器上和/或用户登录会话上启用或停用 CMD.EXE 所有调用的扩展，这要通过设置使用 REGEDT32.EXE 的注册表中的一个或两个 REG_DWORD 值:<br /><br />    HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\EnableExtensions<br /><br />        和/或<br /><br />    HKEY_CURRENT_USER\Software\Microsoft\Command Processor\EnableExtensions<br /><br />到 0x1 或 0x0。用户特定设置比机器设置有优先权。命令行开关比注册表设置有优先权。<br /><br />命令行扩展包括对下列命令所做的更改和/或添加:<br /><br />    DEL 或 ERASE<br />    COLOR<br />    CD 或 CHDIR<br />    MD 或 MKDIR<br />    PROMPT<br />    PUSHD<br />    POPD<br />    SET<br />    SETLOCAL<br />    ENDLOCAL<br />    IF<br />    FOR<br />    CALL<br />    SHIFT<br />    GOTO<br />    START (同时包括对外部命令调用所做的更改)<br />    ASSOC<br />    FTYPE<br /><br />有关详细信息，请键入 HELP 命令名。<br /><br />延迟变量环境扩展不按默认值启用。您可以用/V:ON 或 /V:OFF 命令行开关，为 CMD.EXE 的某个调用而启用或停用延迟环境变量扩充。<br />您可以在机器上和/或用户登录会话上启用或停用 CMD.EXE 所有调用的完成，这要通过设置使用 REGEDT32.EXE 的注册表中的一个或两个 REG_DWORD 值:<br /><br />    HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\DelayedExpansion<br /><br />        和/或<br /><br />    HKEY_CURRENT_USER\Software\Microsoft\Command Processor\DelayedExpansion<br /><br />到 0x1 或 0x0。用户特定设置比机器设置有优先权。命令行开关比注册表设置有优先权。<br /><br />如果延迟环境变量扩充被启用，惊叹号字符可在执行时间，被用来代替一个环境变量的数值。<br /><br />文件和目录名完成不按默认值启用。您可以用 /F:ON 或 /F:OFF 命令行开关，为 CMD.EXE 的某个调用而启用或停用文件名完成。 您可以在机器上和/或用户登录会话上启用或停用 CMD.EXE 所有调用的完成，这要通过设置使用 REGEDT32.EXE 的注册表中的一个或两个 REG_DWORD 值:<br /><br />    HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\CompletionChar<br />    HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\PathCompletionChar<br /><br />        和/或<br /><br />    HKEY_CURRENT_USER\Software\Microsoft\Command Processor\CompletionChar<br />    HKEY_CURRENT_USER\Software\Microsoft\Command Processor\PathCompletionChar<br /><br />由一个控制字符的十六进制值作为一个特定参数(例如，0x4 是 Ctrl-D，0x6 是 Ctrl-F)。 用户特定设置优先于机器设置。命令行开关优先于注册表设置。<br /><br />如果完成是用 /F:ON 命令行开关启用的，两个要使用的控制符是: 目录名字完成用 Ctrl-D， 文件名完成用 Ctrl-F。 要停用注册表中的某个字符，请用空格(0x20)的数值，因为此字符不是控制字符。<br /><br />如果键入两个控制字符中的一个，完成会被调用。完成功能将路径字符串带到光标的左边，如果没有通配符，将通配符附加到左边，并建立相符的路径列表。然后，显示第一个相符的路径。如果没有相符的路径，则发出嘟嘟声，不影响显示。之后，重复按同一个控制字符会循环显示相符路径的列表。将 Shift 键跟控制字符同时按下，会倒着显示列表。如果对该行进行了任何编辑，并再次按下控制字符，保存的相符路径的列表会被丢弃，新的会被生成。如果在文件和目录名完成之间切换，会发生同样现象。两个控制字符之间的唯一区别是文件完成字符符合文件和目录名，而目录完成字符只符合目录名。如果文件完成被用于内置式目录命令(CD、MD 或 RD)，就会使用目录完成。<br /><br />将引号将相符路径括起来，完成代码可以正确处理含有空格或其他特殊字符的文件名。同时，如果备份，然后从行内调用文件完成，完成被调用是位于光标右方的文字会被丢弃。<br /><br />需要引号的特殊字符是:<br />     &lt;space><br />     &()[]{}^=;!'+,`~<br /><br />***************<br /><br />设置默认的控制台前景和背景颜色。<br /><br />COLOR [attr]<br /><br />  attr        指定控制台输出的颜色属性<br /><br />颜色属性由两个十六进制数字指定 -- 第一个为背景，第二个则为前景。每个数字可以为以下任何值之一:<br /><br />    0 = 黑色       8 = 灰色<br />    1 = 蓝色       9 = 淡蓝色<br />    2 = 绿色       A = 淡绿色<br />    3 = 湖蓝色     B = 淡浅绿色<br />    4 = 红色       C = 淡红色<br />    5 = 紫色       D = 淡紫色<br />    6 = 黄色       E = 淡黄色<br />    7 = 白色       F = 亮白色<br /><br />如果没有给定任何参数，该命令会将颜色还原到 CMD.EXE 启动时的颜色。这个值来自当前控制台窗口、/T 开关或 DefaultColor 注册表值。<br /><br />如果用相同的前景和背景颜色来执行 COLOR 命令，COLOR 命令会将 ERRORLEVEL 设置为 1。<br /><br />例如: "COLOR fc" 在亮白色上产生亮红色比较两个文件或两个文件集的内容。<br /><br />***************<br /><br />比较两个或两套文件的内容。<br /><br />COMP [data1] [data2] [/D] [/A] [/L] [/N=number] [/C] [/OFF[LINE]]<br /><br />  data1      指定要比较的第一个文件的位置和名称。<br />  data2      指定要比较的第二个文件的位置和名称。<br />  /D         用十进制格式显示不同处。<br />  /A         用 ASCII 字符显示不同处。<br />  /L         显示不同的行数。<br />  /N=number  只比较每个文件中第一个指定的行数。<br />  /C         比较文件时不分 ASCII 字母的大小写。<br />  /OFF[LINE] 不要跳过带有脱机属性集的文件。<br /><br />要比较文件集，在 data1 和 data2 参数中使用通配符。<br /><br />***************<br /><br />显示或改变 NTFS 分区上文件的压缩.<br /><br />COMPACT [/C | /U] [/S[:dir]] [/A] [/I] [/F] [/Q] [filename [...]]<br /><br />  /C        压缩指定的文件。会给目录作标记，这样以后添加的文件会得到压缩。<br />  /U        解压缩指定的文件。会给目录作标记，这样以后添加的文件不会得到压缩。<br />  /S        在指定的目录和所有子目录中的文件上执行指定操作。默认 "dir"是当前目录。<br />  /A        显示具有隐藏或系统属性的文件。在默认情况下，这些文件都是被忽略的。<br />  /I        即使在错误发生后，依然继续执行指定的操作。在默认情况下，COMPACT 在遇到错误时会停止。<br />  /F        在所有指定文件上强制压缩操作，包括已被压缩的文件。在默认情况下，已经压缩的文件被忽略。<br />  /Q        只报告最重要的信息。<br />  filename  指定类型、文件和目录。<br /><br />  不跟参数一起使用时，COMPACT 显示当前目录及其所含文件的压缩状态。您可以使用多个文件名和通配符。在多个参数之间必须加空格。<br /><br />***************<br /><br />将 FAT 卷转换成 NTFS。<br /><br />CONVERT volume /FS:NTFS [/V] [/CvtArea:filename] [/NoSecurity] [/X]<br /><br />  volume      指定驱动器号(后面跟一个冒号)、装载点或卷名。<br />  /FS:NTFS    指定要被转换成 NTFS 的卷。<br />  /V          指定 Convert 应该用详述模式运行。<br />  /CvtArea:filename<br />              将根目录中的一个接续文件指定为 NTFS 系统文件的占位符。<br />  /NoSecurity 指定每个人都可以访问转换的文件和目录的安全设置。<br />  /X          如果必要，先强行卸载卷。该卷的所有打开的句柄则无效。<br /><br />***************<br /><br />将一份或多份文件复制到另一个位置。<br /><br />COPY [/D] [/V] [/N] [/Y | /-Y] [/Z] [/A | /B ] source [/A | /B] [+ source [/A | /B] [+ ...]] [destination [/A | /B]]<br /><br />  source       指定要复制的文件。<br />  /A           表示一个 ASCII 文本文件。<br />  /B           表示一个二进位文件。<br />  /D           允许解密要创建的目标文件<br />  destination  为新文件指定目录和/或文件名。<br />  /V           验证新文件写入是否正确。<br />  /N           复制带有非 8dot3 名称的文件时，尽可能使用短文件名。<br />  /Y           不使用确认是否要改写现有目标文件的提示。<br />  /-Y          使用确认是否要改写现有目标文件的提示。<br />  /Z           用可重新启动模式复制已联网的文件。<br /><br />命令行开关 /Y 可以在 COPYCMD 环境变量中预先设定。<br />这可能会被命令行上的 /-Y 替代。除非 COPY 命令是在一个批文件脚本中执行的，默认值应为在改写时进行提示。<br /><br />要附加文件，请为目标指定一个文件，为源指定数个文件(用通配符或 file1+file2+file3 格式)。<br /><br />***************<br /><br />显示或设置日期。<br /><br />DATE  [/T | date]<br /><br />显示当前日期设置和输入新日期的提示，请键入不带参数的 DATE。要保留现有日期，请按 ENTER。<br /><br />如果命令扩展名被启用，DATE 命令会支持 /T 开关；该开关指示命令只输出当前日期，但不提示输出新日期。<br /><br />***************<br /><br />删除一个或数个文件。<br /><br />DEL [/P] [/F] [/S] [/Q] [/A[[:]attributes]] names<br />ERASE [/P] [/F] [/S] [/Q] [/A[[:]attributes]] names<br /><br />  names         指定一个或数个文件或目录列表。通配符可被用来删除多个文件。如果指定了一个目录，目录中的所有文件都会被删除。<br /><br />  /P            删除每一个文件之前提示确认。<br />  /F            强制删除只读文件。<br />  /S            从所有子目录删除指定文件。<br />  /Q            安静模式。删除全局通配符时，不要求确认。<br />  /A            根据属性选择要删除的文件。<br />  attributes      R  只读文件                     S  系统文件<br />                  H  隐藏文件                     A  存档文件<br />                  -  表示“否”的前缀<br /><br />如果命令扩展名被启用，DEL 和 ERASE 会如下改变:<br /><br />/S 开关的显示句法会颠倒，即只显示已经删除的文件，而不显示找不到的文件。<br /><br />***************<br /><br />显示目录中的文件和子目录列表。<br /><br />DIR [drive:][path][filename] [/A[[:]attributes]] [/B] [/C] [/D] [/L] [/N] [/O[[:]sortorder]] [/P] [/Q] [/S] [/T[[:]timefield]] [/W] [/X] [/4]<br /><br />  [drive:][path][filename]<br />              指定要列出的驱动器、目录和/或文件。<br /><br />  /A          显示具有指定属性的文件。<br />  attributes   D  目录                R  只读文件<br />               H  隐藏文件            A  准备存档的文件<br />               S  系统文件            -  表示“否”的前缀<br />  /B          使用空格式(没有标题信息或摘要)。<br />  /C          在文件大小中显示千位数分隔符。这是默认值。用 /-C 来停用分隔符显示。<br />  /D          跟宽式相同，但文件是按栏分类列出的。<br />  /L          用小写。<br />  /N          新的长列表格式，其中文件名在最右边。<br />  /O          用分类顺序列出文件。<br />  sortorder    N  按名称(字母顺序)     S  按大小(从小到大)<br />               E  按扩展名(字母顺序)   D  按日期/时间(从先到后)<br />               G  组目录优先           -  颠倒顺序的前缀<br />  /P          在每个信息屏幕后暂停。<br />  /Q          显示文件所有者。<br />  /S          显示指定目录和所有子目录中的文件。<br />  /T          控制显示或用来分类的时间字符域。<br />  timefield   C  创建时间<br />              A  上次访问时间<br />              W  上次写入的时间<br />  /W          用宽列表格式。<br />  /X          显示为非 8dot3 文件名产生的短名称。格式是 /N 的格式，短名称插在长名称前面。如果没有短名称，在其位置则显示空白。<br />  /4          用四位数字显示年<br /><br />可以在 DIRCMD 环境变量中预先设定开关。通过添加前缀 - (破折号)来替代预先设定的开关。例如，/-W。<br /><br />***************<br /><br />比较两张软盘的内容。<br /><br />DISKCOMP [drive1: [drive2:]]<br /><br />把一张软盘的内容复制到另一张。<br /><br />DISKCOPY [drive1: [drive2:]] [/V]<br /><br />  /V   校验信息复制得是否正确。<br /><br />两张软盘的类型必须相同。<br />您可以为 drive1 和 drive2 指定同样的驱动器。<br /><br />***************<br /><br />编辑命令行，重调用 Windows XP 命令，并创建宏。<br /><br />DOSKEY [/REINSTALL] [/LISTSIZE=size] [/MACROS[:ALL | :exename]] [/HISTORY] [/INSERT | /OVERSTRIKE] [/EXENAME=exename] [/MACROFILE=filename] [macroname=[text]]<br /><br />  /REINSTALL          安装一组新的 Doskey。<br />  /LISTSIZE=size      设置命令历史记录的缓冲区大小。<br />  /MACROS             显示所有 Doskey 宏。<br />  /MACROS:ALL         为具有 Doskey 宏的执行文件，显示所有的 Doskey 宏。<br />  /MACROS:exename     显示指定执行文件的所有 Doskey 宏。<br />  /HISTORY            显示保存在内存中的所有命令。<br />  /INSERT             指定用键入的新文字插入旧文字中。<br />  /OVERSTRIKE         指定新文字改写旧文字。<br />  /EXENAME=exename    指定执行文件。<br />  /MACROFILE=filename 指定安装的宏文件。<br />  macroname           指定所创建宏的名称。<br />  text                指定要登记的命令。<br /><br />使用上下箭头键选择命令；ESC 清除命令行；F7 显示命令历史记录；ALT+F7 清除命令历史记录；F8 搜索命令历史记录；F9 按编号选择命令；ALT+F10 清除宏定义。<br /><br />以下是 Doskey 宏定义的特殊码:<br />$T     命令分隔符号。允许一个宏可以含多个命令。<br />$1-$9  批处理参数。与批处理程序中的 %1-%9 相同。<br />$*     以命令行中命令名称后面的任何内容替换的符号。<br /><br />***************<br /><br />显示信息，或将命令回显打开或关上。<br /><br />  ECHO [ON | OFF]<br />  ECHO [message]<br /><br />要显示当前回显设置，键入不带参数的 ECHO。<br /><br />***************<br /><br />结束批处理文件中环境改动的本地化操作。<br /><br />在执行ENDLOCAL 之后所做的环境改动不再仅限于批处理文件。批处理文件结束后，原先的设置无法还原。<br /><br />ENDLOCAL<br /><br />如果命令扩展名被启用，ENDLOCAL 会如下改变:<br /><br />如果相应的 SETLOCAL 用新的 ENABLEEXTENSIONS 或DISABLEEXTENSIONS 选项启用或停用了命令扩展名，那么，在 ENDLOCAL 之后，命令扩展名的启用/停用状态会还原到执行相应的 SETLOCAL 命令前的状态。<br /><br />***************<br /><br />删除一个或数个文件。<br /><br />DEL [/P] [/F] [/S] [/Q] [/A[[:]attributes]] names<br />ERASE [/P] [/F] [/S] [/Q] [/A[[:]attributes]] names<br /><br />  names         指定一个或数个文件或目录列表。通配符可被用来删除多个文件。如果指定了一个目录，目录中的所有文件都会被删除。<br /><br />  /P            删除每一个文件之前提示确认。<br />  /F            强制删除只读文件。<br />  /S            从所有子目录删除指定文件。<br />  /Q            安静模式。删除全局通配符时，不要求确认。<br />  /A            根据属性选择要删除的文件。<br />  attributes      R  只读文件                     S  系统文件<br />                  H  隐藏文件                     A  存档文件<br />                  -  表示“否”的前缀<br /><br />如果命令扩展名被启用，DEL 和 ERASE 会如下改变:<br /><br />/S 开关的显示句法会颠倒，即只显示已经删除的文件，而不显示找不到的文件。<br /><br />***************<br /><br />退出 CMD.EXE 程序(命令翻译程序)或当前批处理脚本。<br /><br />EXIT [/B] [exitCode]<br /><br />  /B          指定要退出当前批处理脚本而不是 CMD.EXE。如果从一个批处理脚本外执行，则会退出 CMD.EXE<br /><br />  exitCode    指定一个数字号码。如果指定了 /B，将 ERRORLEVEL设成那个数字。如果退出 CMD.EXE，则用那个数字设置过程退出代码。<br /><br />***************<br /><br />比较两个文件或两个文件集并显示它们之间的不同<br /><br />FC [/A] [/C] [/L] [/LBn] [/N] [/OFF[LINE]] [/T] [/U] [/W] [/nnnn] [drive1:][path1]filename1 [drive2:][path2]filename2<br />FC /B [drive1:][path1]filename1 [drive2:][path2]filename2<br /><br />  /A         只显示每个不同处的第一行和最后一行。<br />  /B         执行二进制比较。<br />  /C         不分大小写。<br />  /L         将文件作为 ASCII 文字比较。<br />  /LBn       将连续不匹配的最大值设为指定的行数。<br />  /N         在 ASCII 比较上显示行数。<br />  /OFF[LINE] 不要跳过带有脱机属性集的文件。<br />  /T         不要将 tab 扩充到空格。<br />  /U         将文件作为 UNICODE 文字文件比较。<br />  /W         为了比较而压缩空白(tab 和空格)。<br />  /nnnn      指定不匹配处后必须连续匹配的行数。<br />  [drive1:][path1]filename1<br />             指定要比较的第一个文件或第一个文件集。<br />  [drive2:][path2]filename2<br />             指定要比较的第二个文件或第二个文件集。<br /><br />***************<br /><br />在文件中搜索字符串。<br /><br />FIND [/V] [/C] [/N] [/I] [/OFF[LINE]] "string" [[drive:][path]filename[ ...]]<br /><br />  /V        显示所有未包含指定字符串的行。<br />  /C        仅显示包含字符串的行数。<br />  /N        显示行号。<br />  /I        搜索字符串时忽略大小写。<br />  /OFF[LINE] 不要跳过具有脱机属性集的文件。<br />  "string"  指定要搜索的文字串，<br />  [drive:][path]filename<br />            指定要搜索的文件。<br /><br />如果没有指定路径，FIND 将搜索键入的或者由另一命令产生的文字。<br /><br />***************<br /><br />在文件中寻找字符串。<br /><br />FINDSTR [/B] [/E] [/L] [/R] [/S] [/I] [/X] [/V] [/N] [/M] [/O] [/F:file]<br />        [/C:string] [/G:file] [/D:dir list] [/A:color attributes] [/OFF[LINE]]<br />        strings [[drive:][path]filename[ ...]]<br /><br />  /B        在一行的开始配对模式。<br />  /E        在一行的结尾配对模式。<br />  /L        按字使用搜索字符串。<br />  /R        将搜索字符串作为一般表达式使用。<br />  /S        在当前目录和所有子目录中搜索匹配文件。<br />  /I        指定搜索不分大小写。<br />  /X        打印完全匹配的行。<br />  /V        只打印不包含匹配的行。<br />  /N        在匹配的每行前打印行数。<br />  /M        如果文件含有匹配项，只打印其文件名。<br />  /O        在每个匹配行前打印字符偏移量。<br />  /P        忽略有不可打印字符的文件。  <br />  /OFF[LINE] 不跳过带有脱机属性集的文件。<br />  /A:attr   指定有十六进位数字的颜色属性。请见 "color /?"<br />  /F:file   从指定文件读文件列表 (/ 代表控制台)。<br />  /C:string 使用指定字符串作为文字搜索字符串。<br />  /G:file   从指定的文件获得搜索字符串。 (/ 代表控制台)。<br />  /D:dir    查找以分号为分隔符的目录列表<br />  strings   要查找的文字。<br />  [drive:][path]filename<br />            指定要查找的文件。<br /><br />除非参数有 /C 前缀，请使用空格隔开搜索字符串。<br />例如: 'FINDSTR "hello there" x.y' 在文件 x.y 中寻找 "hello" 或 "there" 。 'FINDSTR /C:"hello there" x.y' 文件 x.y  寻找 "hello there"。<br /><br />一般表达式的快速参考:<br />  .        通配符: 任何字符<br />  *        重复: 以前字符或类别出现零或零以上次数<br />  ^        行位置: 行的开始<br />  $        行位置: 行的终点<br />  [class]  字符类别: 任何在字符集中的字符<br />  [^class] 补字符类别: 任何不在字符集中的字符<br />  [x-y]    范围: 在指定范围内的任何字符<br />  \x       Escape: 元字符 x 的文字用法<br />  \&lt;xyz    字位置: 字的开始<br />  xyz\>    字位置: 字的结束<br /><br />有关 FINDSTR 常见表达法的详细情况，请见联机命令参考。<br /><br />***************<br /><br />对一组文件中的每一个文件执行某个特定命令。<br /><br />FOR %variable IN (set) DO command [command-parameters]<br /><br />  %variable  指定一个单一字母可替换的参数。<br />  (set)      指定一个或一组文件。可以使用通配符。<br />  command    指定对每个文件执行的命令。<br />  command-parameters<br />             为特定命令指定参数或命令行开关。<br /><br />在批处理文件中使用 FOR 命令时，指定变量请使用 %%variable 而不要用 %variable。变量名称是区分大小写的，所以 %i 不同于 %I.<br /><br />如果命令扩展名被启用，下列额外的 FOR 命令格式会受到支持:<br /><br />FOR /D %variable IN (set) DO command [command-parameters]<br /><br />    如果集中包含通配符，则指定与目录名匹配，而不与文件名匹配。<br /><br />FOR /R [[drive:]path] %variable IN (set) DO command [command-parameters]<br /><br />    检查以 [drive:]path 为根的目录树，指向每个目录中的 FOR 语句。如果在 /R 后没有指定目录，则使用当前目录。如果集仅为一个单点(.)字符，则枚举该目录树。<br /><br />FOR /L %variable IN (start,step,end) DO command [command-parameters]<br /><br />    该集表示以增量形式从开始到结束的一个数字序列。因此，(1,1,5) 将产生序列 1 2 3 4 5，(5,-1,1) 将产生序列 (5 4 3 2 1)。<br /><br />FOR /F ["options"] %variable IN (file-set) DO command [command-parameters]<br />FOR /F ["options"] %variable IN ("string") DO command [command-parameters]<br />FOR /F ["options"] %variable IN ('command') DO command [command-parameters]<br /><br />    或者，如果有 usebackq 选项:<br /><br />FOR /F ["options"] %variable IN (file-set) DO command [command-parameters]<br />FOR /F ["options"] %variable IN ("string") DO command [command-parameters]<br />FOR /F ["options"] %variable IN ('command') DO command [command-parameters]<br /><br />    filenameset 为一个或多个文件名。继续到 filenameset 中的下一个文件之前，每份文件都已被打开、读取并经过处理。处理包括读取文件，将其分成一行行的文字，然后将每行解析成零或更多的符号。然后用已找到的符号字符串变量值调用 For 循环。以默认方式，/F 通过每个文件的每一行中分开的第一个空白符号。跳过空白行。您可通过指定可选 "options"  参数替代默认解析操作。这个带引号的字符串包括一个或多个指定不同解析选项的关键字。这些关键字为:<br /><br />        eol=c           - 指一个行注释字符的结尾(就一个)<br />        skip=n          - 指在文件开始时忽略的行数。<br />        delims=xxx      - 指分隔符集。这个替换了空格和跳格键的默认分隔符集。<br />        tokens=x,y,m-n  - 指每行的哪一个符号被传递到每个迭代的 for 本身。这会导致额外变量名称的分配。m-n 格式为一个范围。通过 nth 符号指定 mth。如果符号字符串中的最后一个字符星号，那么额外的变量将在最后一个符号解析之后分配并接受行的保留文本。<br />        usebackq        - 指定新语法已在下类情况中使用: 在作为命令执行一个后引号的字符串并且一个单引号字符为文字字符串命令并允许在 filenameset 中使用双引号扩起文件名称。<br /><br />    某些范例可能有助:<br /><br />FOR /F "eol=; tokens=2,3* delims=, " %i in (myfile.txt) do @echo %i %j %k<br /><br />    会分析 myfile.txt 中的每一行，忽略以分号打头的那些行，将每行中的第二个和第三个符号传递给 for 程序体；用逗号和/或空格定界符号。请注意，这个 for 程序体的语句引用 %i 来取得第二个符号，引用 %j 来取得第三个符号，引用 %k 来取得第三个符号后的所有剩余符号。对于带有空格的文件名，您需要用双引号将文件名括起来。为了用这种方式来使用双引号，您还需要使用 usebackq 选项，否则，双引号会 被理解成是用作定义某个要分析的字符串的。<br /><br />    %i 专门在 for 语句中得到说明，%j 和 %k 是通过 tokens= 选项专门得到说明的。您可以通过 tokens= 一行指定最多 26 个符号，只要不试图说明一个高于字母 'z' 或 'Z' 的变量。请记住，FOR 变量是单一字母、分大小写和全局的；而且，同时不能有 52 个以上都在使用中。<br /><br />    您还可以在相邻字符串上使用 FOR /F 分析逻辑；方法是，用单引号将括号之间的 filenameset 括起来。这样，该字符串会被当作一个文件中的一个单一输入行。<br /><br />    最后，您可以用 FOR /F 命令来分析命令的输出。方法是，将括号之间的 filenameset 变成一个反括字符串。该字符串会被当作命令行，传递到一个子 CMD.EXE，其输出会被抓进内存，并被当作文件分析。因此，以下例子:<br /><br />      FOR /F "usebackq delims==" %i IN (`set`) DO @echo %i<br /><br />    会枚举当前环境中的环境变量名称。<br /><br />另外，FOR 变量参照的替换已被增强。您现在可以使用下列选项语法:<br /><br />     ~I         - 删除任何引号(")，扩充 %I<br />     %~fI        - 将 %I 扩充到一个完全合格的路径名<br />     %~dI        - 仅将 %I 扩充到一个驱动器号<br />     %~pI        - 仅将 %I 扩充到一个路径<br />     %~nI        - 仅将 %I 扩充到一个文件名<br />     %~xI        - 仅将 %I 扩充到一个文件扩展名<br />     %~sI        - 扩充的路径只含有短名<br />     %~aI        - 将 %I 扩充到文件的文件属性<br />     %~tI        - 将 %I 扩充到文件的日期/时间<br />     %~zI        - 将 %I 扩充到文件的大小<br />     %~$PATH:I   - 查找列在路径环境变量的目录，并将 %I 扩充到找到的第一个完全合格的名称。如果环境变量名未被定义，或者没有找到文件，此组合键会扩充到空字符串<br /><br />可以组合修饰符来得到多重结果:<br /><br />     %~dpI       - 仅将 %I 扩充到一个驱动器号和路径<br />     %~nxI       - 仅将 %I 扩充到一个文件名和扩展名<br />     %~fsI       - 仅将 %I 扩充到一个带有短名的完整路径名<br />     %~dp$PATH:i - 查找列在路径环境变量的目录，并将 %I 扩充到找到的第一个驱动器号和路径。 <br />     %~ftzaI     - 将 %I 扩充到类似输出线路的 DIR<br /><br />在以上例子中，%I 和 PATH 可用其他有效数值代替。%~ 语法用一个有效的 FOR 变量名终止。选取类似 %I 的大写变量名比较易读，而且避免与不分大小写的组合键混淆。<br /><br />***************<br /><br />格式化磁盘以供 Windows XP 使用。<br /><br />FORMAT volume [/FS:file-system] [/V:label] [/Q] [/A:size] [/C] [/X]<br />FORMAT volume [/V:label] [/Q] [/F:size]<br />FORMAT volume [/V:label] [/Q] [/T:tracks /N:sectors]<br />FORMAT volume [/V:label] [/Q]<br />FORMAT volume [/Q]<br /><br />  volume           指定驱动器(后面跟一个冒号)、装入点或卷名。<br />  /FS:filesystem  指定文件系统类型(FAT、FAT32 或 NTFS)。<br />  /V:label        指定卷标。<br />  /Q              执行快速格式化。<br />  /C              仅适于 NTFS: 默认情况下，将压缩在该新建卷上创建的文件。<br />   /X              如果必要，先强制卸下卷。那时，该卷所有已打开的句柄不再有效。<br />  /A:size         替代默认配置单位大小。极力建议您在一般状况下使用默认设置。<br />                  NTFS 支持 512、1024、2048、4096、8192、16K、32K、64K。<br />                  FAT 支持 512、1024、2048、4096、8192、16K、32K、64k，(128k、256k 用于大于 512 字节的扇区) 。 <br />                  FAT32 支持 512、1024、2048、4096、8192、16k、32k、64k，(128k 、256k 用于大于 512 字节的扇区)。<br />                        <br />                  注意 FAT 及 FAT32 文件系统对卷上的群集数量有以下限制: <br /><br />                  FAT: 群集数量 &lt;= 65526 <br />                  FAT32: 65526 &lt; 群集数量 &lt; 4177918<br /><br />                  如果判定使用指定的群集大小无法满足以上需求，格式化将立即停止。<br /><br />                  NTFS 压缩不支持大于 4096 的分配单元。<br /><br />  /F:size         指定要格式化的软盘大小(1.44)<br />  /T:tracks       为磁盘指定每面磁道数。<br />  /N:sectors      指定每条磁道的扇区数。<br /><br />***************<br /><br />显示或修改用在文件扩展名关联中的文件类型<br /><br />FTYPE [fileType[=[openCommandString]]]<br /><br />  fileType  指定要检查或改变的文件类型<br />  openCommandString 指定调用这类文件时要使用的开放式命令。<br /><br />键入 FTYPE 而不带参数来显示当前有定义的开放式命令字符串的文件类型。 FTYPE 仅用一个文件类型启用时，它显示那个文件类型目前的开放式命令字符串。如果不为开放式命令字符串指定，FTYPE 命令将删除那个文件类型的开放式命令字符串。在一个开放式命令字符串之内，命令字符串 %0 或 %1 被通过关联调用的文件名所代替。%* 得到所有的参数，%2 得到第一个参数，%3 得到第二个，等等。%~n 得到其余所有以 nth 参数打头的参数；n 可以是从 2 到 9 的数字。例如:<br /><br />    ASSOC .pl=PerlScript<br />    FTYPE PerlScript=perl.exe %1 %*<br /><br />允许您启用以下 Perl 脚本:<br /><br />    script.pl 1 2 3<br /><br />如果不想键入扩展名，则键入以下字符串:<br /><br />    set PATHEXT=.pl;%PATHEXT%<br /><br />被启动的脚本如下:<br /><br />    script 1 2 3<br /><br />***************<br /><br />将 cmd.exe 导向到批处理程序中带标签的行。<br /><br />GOTO label<br /><br />  label   指定批处理程序中用作标签的文字字符串。<br /><br />标签必须单独一行，并且以冒号打头。<br /><br />如果命令扩展名被启用，GOTO 会如下改变:<br /><br />GOTO 命令现在接受目标标签 :EOF，这个标签将控制转移到当前批脚本文件的结尾。不定义就退出批脚本文件，这是一个容易的办法。有关能使该功能有用的 CALL 命令的扩展名描述，请键入CALL /?。<br /><br />***************<br /><br />请在图形模式下启用 Windows 显示扩展字符集。<br /><br />GRAFTABL [xxx]<br />GRAFTABL /STATUS<br /><br />   xxx      指定代码页。<br />   /STATUS  显示选定的同 GRAFTABL 一起使用的当前代码页。<br /><br />***************<br /><br />提供 Windows XP 命令的帮助信息。<br /><br />HELP [command]<br /><br />    command - 显示该命令的帮助信息。<br /><br />***************<br /><br />执行批处理程序中的条件处理。<br /><br />IF [NOT] ERRORLEVEL number command<br />IF [NOT] string1==string2 command<br />IF [NOT] EXIST filename command<br /><br />  NOT               指定只有条件为 false 的情况下， Windows XP 才应该执行该命令。<br /><br />  ERRORLEVEL number 如果最后运行的程序返回一个等于或大于指定数字的退出编码，指定条件为 true。<br /><br />  string1==string2  如果指定的文字字符串匹配，指定条件为 true。<br /><br />  EXIST filename    如果指定的文件名存在，指定条件为 true。<br /><br />  command           如果符合条件，指定要执行的命令。如果指定的条件为 FALSE，命令后可跟一个执行 ELSE 关键字后的命令的 ELSE 命令。<br /><br />ELSE 子句必须在 IF 之后出现在同一行上。例如:<br /><br />    IF EXIST filename. (<br />        del filename.<br />    ) ELSE (<br />        echo filename. missing.<br />    )<br /><br />因为 del 命令需要用一个新行终止，以下子句不会有效:<br /><br />IF EXIST filename. del filename. ELSE echo filename. missing<br /><br />由于 ELSE 命令必须与 IF 命令的尾端在同一行上，以下子句也不会有效:<br /><br />    IF EXIST filename. del filename.<br />    ELSE echo filename. missing<br /><br />如果都放在同一行上，以下子句有效:<br /><br />    IF EXIST filename. (del filename.) ELSE echo filename. missing<br /><br />如果命令扩展名被启用，IF 会如下改变:<br /><br />    IF [/I] string1 compare-op string2 command<br />    IF CMDEXTVERSION number command<br />    IF DEFINED variable command<br /><br />其中，比较运算符可以是:<br /><br />    EQU - 等于<br />    NEQ - 不等于<br />    LSS - 小于<br />    LEQ - 小于或等于<br />    GTR - 大于<br />    GEQ - 大于或等于<br /><br />及 /I 开关；如果该开关被指定，则说明要进行的字符串比较不分大小写。/I 开关可以用于 IF 的 string1==string2 的形式上。这些比较都是通用的；原因是，如果 string1 和 string2 都是由数字组成的，字符串会被转换成数字，进行数字比较。<br /><br />CMDEXTVERSION 条件的作用跟 ERRORLEVEL 的一样，除了它是在跟与命令扩展名有关联的内部版本号比较。第一个版本是 1。每次对命令扩展名有相当大的增强时，版本号会增加一个。<br />命令扩展名被停用时，CMDEXTVERSION 条件不是真的。<br /><br />如果已定义环境变量，DEFINED 条件的作用跟 EXISTS 的一样，除了它取得一个环境变量，返回的结果是 true。<br /><br />如果没有名为 ERRORLEVEL 的环境变量，%ERRORLEVEL% 会扩充为 ERROLEVEL 当前数值的字符串表达式；否则，您会得到其数值。运行程序后，以下语句说明 ERRORLEVEL 的用法:<br /><br />    goto answer%ERRORLEVEL%<br />    :answer0<br />    echo Program had return code 0<br />    :answer1<br />    echo Program had return code 1<br /><br />您也可以使用以上的数字比较:<br /><br />    IF %ERRORLEVEL% LEQ 1 goto okay<br /><br />如果没有名为 CMDCMDLINE 的环境变量，%CMDCMDLINE% 将在 CMD.EXE 进行任何处理前扩充为传递给 CMD.EXE 的原始命令行；否则，您会得到其数值。<br /><br />如果没有名为 CMDEXTVERSION 的环境变量，%CMDEXTVERSION% 会扩充为 CMDEXTVERSION 当前数值的字串符表达式；否则，您会得到其数值。<br /><br />***************<br /><br />创建、更改或删除磁盘的卷标。<br /><br />LABEL [drive:][label]<br />LABEL [/MP] [volume] [label]<br /><br />  drive:          指定驱动器名。<br />  label           指定卷标签。<br />  /MP             指定卷应该被当作安装点或卷名。<br />  volume          指定驱动器(后面跟一个冒号)、装入点或卷名。如果指定了卷名，/MP 标志则不必要。<br /><br />***************<br /><br />创建目录。<br /><br />MKDIR [drive:]path<br />MD [drive:]path<br /><br />如果命令扩展名被启用，MKDIR 会如下改变:<br /><br />如果需要，MKDIR 会在路径中创建中级目录。例如: 假设 \a 不存在，那么:<br /><br />    mkdir \a\b\c\d<br /><br />与:<br /><br />    mkdir \a<br />    chdir \a<br />    mkdir b<br />    chdir b<br />    mkdir c<br />    chdir c<br />    mkdir d<br /><br />相同。如果扩展名被停用，则需要键入 mkdir \a\b\c\d。<br /><br />***************<br /><br />配置系统设备。<br /><br />串行口:　　　   MODE COMm[:] [BAUD=b] [PARITY=p] [DATA=d] [STOP=s] [to=on|off] [xon=on|off] [odsr=on|off] [octs=on|off] [dtr=on|off|hs] [rts=on|off|hs|tg] [idsr=on|off]<br /><br />设备状态:       MODE [device] [/STATUS]<br /><br />打印重定向:　　 MODE LPTn[:]=COMm[:]<br /><br />选定代码页:　　 MODE CON[:] CP SELECT=yyy<br /><br />代码页状态:　　 MODE CON[:] CP [/STATUS]<br /><br />显示模式:　　   MODE CON[:] [COLS=c] [LINES=n]<br /><br />击键率:　       MODE CON[:] [RATE=r DELAY=d]<br /><br />***************<br /><br />逐屏显示输出。<br /><br />MORE [/E [/C] [/P] [/S] [/Tn] [+n]] &lt; [drive:][path]filename<br />command-name | MORE [/E [/C] [/P] [/S] [/Tn] [+n]]<br />MORE /E [/C] [/P] [/S] [/Tn] [+n] [files]<br /><br />    [drive:][path]filename  指定要逐屏显示的文件。<br /><br />    command-name            指定要显示其输出的命令 。<br /><br />    /E      启用扩展功能<br />    /C      显示页面前先清除屏幕<br />    /P      扩展 FormFeed 字符<br />    /S      将多个空白行缩成一行<br />    /Tn     将跳格键扩展成 n 个空格(默认值为 8)命令行开关可以出现在 MORE 环境变量中。<br /><br />    +n      从第 n 行开始显示第一个文件<br /><br />    files    要显示的文件列表。 用空格分开列表中的文件。<br /><br />    如果扩展的功能已经启用，在 -- More -- 提示处会接受下列命令:<br /><br />    P n     显示下 n 行<br />    S n     略过下 n 行<br />    F       显示下个文件<br />    Q       退出<br />    =       显示行号<br />    ?       显示帮助行<br />    &lt;space> 显示下一页<br />    &lt;ret>   显示下一行<br /><br />***************<br /><br />移动文件并重命名文件和目录。<br /><br />要移动至少一个文件:<br />MOVE [/Y | /-Y] [drive:][path]filename1[,...] destination<br /><br />要重命名一个目录:<br />MOVE [/Y | /-Y] [drive:][path]dirname1 dirname2<br /><br />  [drive:][path]filename1 指定您想移动的文件位置和名称。<br />  destination             指定文件的新位置。目标可包含一个驱动器号和冒号、一个目录名或组合。如果只移动一个文件并在移动时将其重命名，您还可以包括文件名。<br />  [drive:][path]dirname1  指定要重命名的目录。<br />  dirname2                指定目录的新名称。<br /><br />  /Y                      取消确认改写一个现有目标文件的提示。<br />  /-Y                     对确认改写一个现有目标文件发出提示。<br /><br />命令行开关 /Y 可以出现在 COPYCMD 环境变量中。这可以用命令行上的 /-Y 替代。默认值是，除非 MOVE 命令是从一个批脚本内执行的，改写时都发出提示。<br /><br />***************<br /><br />为可执行文件显示或设置一个搜索路径。<br /><br />PATH [[drive:]path[;...][;%PATH%]<br />PATH ;<br /><br />键入 PATH ; 清除所有搜索路径设置并指示 cmd.exe 只在当前目录中搜索。<br />键入 PATH 但不加参数，显示当前路径。<br />将 %PATH% 包括在新的路径设置中会将旧路径附加到新设置。<br /><br />***************<br /><br />命令选项到保存在 PUSHD 命令里的目录。<br /><br />POPD<br /><br />如果命令扩展名被启用，从推目录堆栈 POPD 驱动器时，POPD 命令会删除 PUSHD 创建的临时驱动器号。<br /><br />***************<br /><br />打印文本文件。<br /><br />PRINT [/D:device] [[drive:][path]filename[...]]<br /><br />   /D:device   指定打印机设备。<br /><br />***************<br /><br />更改 cmd.exe 命令提示符。<br /><br />PROMPT [text]<br /><br />  text    指定新的命令提示符。<br /><br />提示符可以由普通字符及下列特定代码组成:<br /><br />  $A   & (短 and 符号)<br />  $B   | (管道)<br />  $C   ( (左括弧)<br />  $D   当前日期<br />  $E   Escape code (ASCII 码 27)<br />  $F   ) (右括弧)<br />  $G   > (大于符号)<br />  $H   Backspace (擦除前一个字符)<br />  $L   &lt; (小于符号)<br />  $N   当前驱动器<br />  $P   当前驱动器及路径<br />  $Q    = (等号)<br />  $S     (空格)<br />  $T   当前时间<br />  $V   Windows XP 版本号<br />  $_   换行<br />  $$   $ (货币符号)<br /><br />如果命令扩展名被启用，PROMPT 命令会支持下列格式化字符:<br /><br />  $+   根据 PUSHD 目录堆栈的深度，零个或零个以上加号(+)字符；每个被推的层有一个字符。<br /><br />  $M   如果当前驱动器不是网络驱动器，显示跟当前驱动器号或空字符串有关联的远程名。<br /><br />***************<br /><br />保存当前目录以供 POPD 命令使用，然后改到指定的目录。<br /><br />PUSHD [path | ..]<br /><br />  path   指定要成为当前目录的目录。<br /><br />如果命令扩展名被启用，除了一般驱动器号和路径，PUSHD 命令还接受网络路径。如果指定了网络路径，PUSHD 将创建一个指向指定网络资源的临时驱动器号，然后再用刚定义的驱动器号改变当前的驱动器和目录。可以从 Z: 往下分配临时驱动器号，使用找到的第一个没有用过的驱动器号。<br /><br />***************<br /><br />删除一个目录。<br /><br />RMDIR [/S] [/Q] [drive:]path<br />RD [/S] [/Q] [drive:]path<br /><br />    /S      除目录本身外，还将删除指定目录下的所有子目录和文件。用于删除目录树。<br /><br />    /Q      安静模式，带 /S 删除目录树时不要求确认从损坏的磁盘中恢复可读取的信息。<br /><br />***************<br /><br />从有问题的磁盘恢复可读信息。<br />RECOVER [drive:][path]filename<br />在使用 RECOVER 命令以前，先查阅 Windows XP 帮助内的联机命令参考。<br /><br />***************<br /><br />在批处理文件或 CONFIG.SYS 里加上注解或说明。<br /><br />REM [comment]<br /><br />***************<br /><br />重命名文件。<br /><br />RENAME [drive:][path]filename1 filename2.<br />REN [drive:][path]filename1 filename2.<br /><br />请注意，您不能为目标文件指定新的驱动器或路径。<br />重命名文件。<br /><br />RENAME [drive:][path]filename1 filename2.<br />REN [drive:][path]filename1 filename2.<br /><br />请注意，您不能为目标文件指定新的驱动器或路径。<br /><br />***************<br /><br />替换文件。<br /><br />REPLACE [drive1:][path1]filename [drive2:][path2] [/A] [/P] [/R] [/W]<br />REPLACE [drive1:][path1]filename [drive2:][path2] [/P] [/R] [/S] [/W] [/U]<br /><br />  [drive1:][path1]filename 指定源文件。<br />  [drive2:][path2]         指定要替换文件的目录。<br />  /A                       把新文件加入目标目录。不能和 /S 或 /U 命令行开关搭配使用。<br />  /P                       替换文件或加入源文件之前会先提示您进行确认。<br />  /R                       替换只读文件以及未受保护的文件。<br />  /S                       替换目标目录中所有子目录的文件。不能与 /A 命令选项搭配使用。<br />  /W                       等您插入磁盘以后再运行。<br />  /U                       只会替换或更新比源文件日期早的文件。<br />                           不能与 /A 命令行开关搭配使用。<br /><br />***************<br /><br />删除一个目录。<br /><br />RMDIR [/S] [/Q] [drive:]path<br />RD [/S] [/Q] [drive:]path<br /><br />    /S      除目录本身外，还将删除指定目录下的所有子目录和文件。用于删除目录树。<br /><br />    /Q      安静模式，带 /S 删除目录树时不要求确认<br /><br />***************<br /><br />显示、设置或删除 cmd.exe 环境变量。<br /><br />SET [variable=[string]]<br /><br />  variable  指定环境变量名。<br />  string    指定要指派给变量的一系列字符串。<br /><br />要显示当前环境变量，键入不带参数的 SET。<br /><br />如果命令扩展名被启用，SET 会如下改变:<br /><br />可仅用一个变量激活 SET 命令，等号或值不显示所有前缀匹配 SET 命令已使用的名称的所有变量的值。例如:<br /><br />    SET P<br /><br />会显示所有以字母 P 打头的变量<br /><br />如果在当前环境中找不到该变量名称，SET 命令将把 ERRORLEVEL 设置成 1。<br /><br />SET 命令不允许变量名含有等号。<br /><br />在 SET 命令中添加了两个新命令行开关:<br /><br />    SET /A expression<br />    SET /P variable=[promptString]<br /><br />/A 命令行开关指定等号右边的字符串为被评估的数字表达式。该表达式评估器很简单并以递减的优先权顺序支持下列操作:<br /><br />    ()                  - 分组<br />    ! ~ -               - 一元运算符<br />    * / %               - 算数运算符<br />    + -                 - 算数运算符<br />    &lt;&lt; >>               - 逻辑移位<br />                       - 按位“与”<br />    ^                   - 按位“异”<br />    |                   - 按位“或”<br />    = *= /= %= += -=    - 赋值<br />      &= ^= |= &lt;&lt;= >>=<br />    ,                   - 表达式分隔符<br /><br />如果您使用任何逻辑或取余操作符， 您需要将表达式字符串用引号扩起来。在表达式中的任何非数字字符串键作为环境变量名称，这些环境变量名称的值已在使用前转换成数字。如果指定了一个环境变量名称，但未在当前环境中定义，那么值将被定为零。这使您可以使用环境变量值做计算而不用键入那些 % 符号来得到它们的值。如果 SET /A 在命令脚本外的命令行执行的，那么它显示该表达式的最后值。该分配的操作符在分配的操作符左边需要一个环境变量名称。除十六进制有 0x 前缀， 八进制有 0 前缀的，数字值为十进位数字。因此， 0x12 与 18 和 022 相同。请注意八进制公式可能很容易搞混: 08 和 09 是无效的数字，因为 8 和 9 不是有效的八进制位数。<br /><br />/P 命令行开关允许将变量数值设成用户输入的一行输入。读取输入行之前，显示指定的 promptString。promptString 可以是空的。<br /><br />环境变量替换已如下增强:<br /><br />    %PATH:str1=str2%<br /><br />会扩展 PATH 环境变量，用 "str2" 代替扩展结果中的每个 "str1"。要有效地从扩展结果中删除所有的 "str1"，"str2" 可以是空的。"str1" 可以以星号打头；在这种情况下，"str1" 会从扩展结果的开始到 str1 剩余部分第一次出现的地方，都一直保持相配。<br /><br />也可以为扩展名指定子字符串。<br /><br />    %PATH:~10,5%<br /><br />会扩展 PATH 环境变量，然后只使用在扩展结果中从第 11 个(偏移量 10)字符开始的五个字符。如果没有指定长度，则采用默认值，即变量数值的余数。如果两个数字(偏移量和长度)都是负数，使用的数字则是环境变量数值长度加上指定的偏移量或长度。<br /><br />    %PATH:~-10%<br /><br />会提取 PATH 变量的最后十个字符。<br /><br />    %PATH:~0,-2%<br /><br />会提取 PATH 变量的所有字符，除了最后两个。<br /><br />终于添加了延迟环境变量扩充的支持。该支持总是按默认值被停用，但也可以通过 CMD.EXE 的 /V 命令行开关而被启用/停用。<br />请参阅 CMD /?<br /><br />考虑到读取一行文本时所遇到的目前扩充的限制时，延