<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    byterat

      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      54 隨筆 :: 0 文章 :: 15 評論 :: 0 Trackbacks

    2007年5月17日 #

    Eclipse及其插件介紹和下載

    0.Eclipse下載
    EMF,GEF - Graphical Editor Framework,UML2,VE - Visual Editor都在這里下載
    http://www.eclipse.org/downloads/index.php

    0.5.lomboz J2EE插件,開發(fā)JSP,EJB
    http://forge.objectweb.org/projects/lomboz
    1.MyEclipse J2EE開發(fā)插件,支持SERVLET/JSP/EJB/數(shù)據(jù)庫操縱等
    http://www.myeclipseide.com

    2.Properties Editor 編輯java的屬性文件,并可以自動存盤為Unicode格式
    http://propedit.sourceforge.jp/index_en.html

    3.Colorer Take 為上百種類型的文件按語法著色
    http://colorer.sourceforge.net/

    4.XMLBuddy 編輯xml文件
    http://www.xmlbuddy.com

    5.Code Folding 加入多種代碼折疊功能(比eclipse自帶的更多)
    http://www.coffee-bytes.com/servlet/PlatformSupport

    6.Easy Explorer 從eclipse中訪問選定文件、目錄所在的文件夾
    http://easystruts.sourceforge.net/

    7.Fat Jar 打包插件,可以方便的完成各種打包任務(wù),可以包含外部的包等
    http://fjep.sourceforge.net/

    8.RegEx Test 測試正則表達(dá)式
    http://brosinski.com/stephan/archives/000028.php

    9.JasperAssistant 報表插件(強(qiáng),要錢的)
    http://www.jasperassistant.com/

    10.Jigloo GUI Builder JAVA的GUI編輯插件
    http://cloudgarden.com/jigloo/

    11.Profiler 性能跟蹤、測量工具,能跟蹤、測量BS程序
    http://sourceforge.net/projects/eclipsecolorer/

    12.AdvanQas 提供對if/else等條件語句的提示和快捷幫助(自動更改結(jié)構(gòu)等)
    http://eclipsecolorer.sourceforge.net/advanqas/index.html

    13.Log4E Log4j插件,提供各種和Log4j相關(guān)的任務(wù),如為方法、類添加一個logger等
    http://log4e.jayefem.de/index.php/Main_Page

    14.VSSPlugin VSS插件
    http://sourceforge.net/projects/vssplugin

    15.Implementors 提供跳轉(zhuǎn)到一個方法的實(shí)現(xiàn)類,而不是接中的功能(實(shí)用!)
    http://eclipse-tools.sourceforge.net/implementors/
    16.Call Hierarchy 顯示一個方法的調(diào)用層次(被哪些方法調(diào),調(diào)了哪些方法)
    http://eclipse-tools.sourceforge.net/call-hierarchy/index.html

    17.EclipseTidy 檢查和格式化HTML/XML文件
    http://eclipsetidy.sourceforge.net/

    18.Checkclipse 檢查代碼的風(fēng)格、寫法是否符合規(guī)范
    http://www.mvmsoft.de/content/plugins/checkclipse/checkclipse.htm

    19.Hibernate Synchronizer Hibernate插件,自動映射等
    http://www.binamics.com/hibernatesync/

    20.VeloEclipse Velocity插件
    http://propsorter.sourceforge.net/

    21.EditorList 方便的列出所有打開的Editor
    http://editorlist.sourceforge.net/

    22.MemoryManager 內(nèi)存占用率的監(jiān)視
    http://cloudgarden.com/memorymanager/

    23.swt-designer java的GUI插件
    http://www.swt-designer.com/

    24.TomcatPlugin 支持Tomcat插件
    http://www.eclipsetotale.com/tomcatPlugin.html

    25.XML Viewer
    http://tabaquismo.freehosting.net/ignacio/eclipse/xmlview/index.html

    26.quantum 數(shù)據(jù)庫插件
    http://quantum.sourceforge.net/

    27.Dbedit 數(shù)據(jù)庫插件
    http://sourceforge.net/projects/dbedit

    28.clay.core 可視化的數(shù)據(jù)庫插件
    http://www.azzurri.jp/en/software/index.jsp
    http://www.azzurri.jp/eclipse/plugins

    29.hiberclipse hibernate插件
    http://hiberclipse.sourceforge.net
    http://www.binamics.com/hibernatesync

    30.struts-console Struts插件
    http://www.jamesholmes.com/struts/console/

    31.easystruts Struts插件
    http://easystruts.sourceforge.net

    32.veloedit Velocity插件
    http://veloedit.sourceforge.net/

    33.jalopy 代碼整理插件
    http://jalopy.sourceforge.net/

    34.JDepend 包關(guān)系分析
    http://andrei.gmxhome.de/jdepend4eclipse/links.html

    35.Spring IDE Spring插件
    http://springide-eclip.sourceforge.net/updatesite/

    36.doclipse 可以產(chǎn)生xdoclet 的代碼提示
    http://beust.com/doclipse/
    posted @ 2008-06-05 15:44 比特鼠| 編輯 收藏

         摘要: 有這樣一個函數(shù), 它接受一個函數(shù)(或者說閉包)作為參數(shù)  閱讀全文
    posted @ 2008-05-30 15:19 比特鼠| 編輯 收藏

    當(dāng)談到表格數(shù)據(jù)的設(shè)計時,沒有太多的網(wǎng)頁設(shè)計師會有太大的興趣。今天我們已經(jīng)收集了20多個功能超大且看上去挺漂亮的Ajax/CSS表格設(shè)計,并且教你一些表格設(shè)計中所運(yùn)用的技巧,例如表格數(shù)據(jù)的排序和過濾等。

    OK,讓我們來看一下這些表格:

    1. Tablecloth

    Tablecloth 由CSS Globe 開發(fā),是一個輕巧易于使用的表格,簡潔的將表格樣式添加到你的HTML 表格元素中。

    21個新奇漂亮的Ajax/CSS表格設(shè)計-Tablecloth

    2. Ask the CSS Guy Table

    Ask the CSS Guy Table教給我們要如何去創(chuàng)建能夠清晰顯出去資料之間的相關(guān)聯(lián)系的表格,例如:點(diǎn)擊一個表格元素時,將突了顯示這個元素,并且在縱列和橫列都顯示出相關(guān)的類別關(guān)系。

    21個新奇漂亮的Ajax/CSS表格設(shè)計-Ask the CSS Guy Table

    #3. A CSS styled table version 2

    Veerle Duoh 為我們展示了一個漂亮的表格設(shè)計,并教我們?nèi)绾问褂肅SS來吸引用戶的眼球。

    21個新奇漂亮的Ajax/CSS表格設(shè)計-A CSS styled table version 2

    #4. Sortable Table

    Sortable Table 演示了如何按升序或降序排列以及如何過濾表格中的數(shù)據(jù)。

    21個新奇漂亮的Ajax/CSS表格設(shè)計-Sortable Table

    5. Row Locking with CSS and JavaScript

    Css Guy再次對表格使用了聚焦高亮的效果,除非用戶再次點(diǎn)擊,否則表單數(shù)據(jù)將一直保持亮高。

    21個新奇漂亮的Ajax/CSS表格設(shè)計-Row Locking with CSS and JavaScript

    他還給了我們另一個示例:another example to Lock rows with radios .

    #6. Vertical scrolling tables

    如果您有大量的表格數(shù)據(jù),但卻沒有太大的空間來展示它,這可能是個比較好的方法:一個純CSS的表格與固定的標(biāo)題和頁腳,以及滾動顯示的內(nèi)容。

    21個新奇漂亮的Ajax/CSS表格設(shè)計-Vertical scrolling tables

    7. Replicating a Tree table

    這是一個使用HTML 和CSS 設(shè)計的樹形狀表格。

    21個新奇漂亮的Ajax/CSS表格設(shè)計-Replicating a Tree table

    8 ) Paginate, sort and search a table with Ajax and Rails

    這個表格提供了一個動態(tài)的界面,而不需要重新刷新整個頁面。

    21個新奇漂亮的Ajax/CSS表格設(shè)計-ajax tables

    9. Collapsible tables with DOM and CSS

    此表格加上箭頭形象的腳本提示,用來控制表格的伸展和收縮。

    21個新奇漂亮的Ajax/CSS表格設(shè)計-Collapsible tables with DOM and CSS

    10. TableSorter plug-in for jQuery

    它的主要特性包括多列排序,支持<TH>的rowspan和colspan屬性以及許多其他功能。

    21個新奇漂亮的Ajax/CSS表格設(shè)計-TableSorter plug-in for jQuery

    11. Stripe your tables the OO way

    使用了Javascript 為表格中的行進(jìn)行顏色交替,并且添加了onmouseoveronmouseout 事件,當(dāng)鼠標(biāo)點(diǎn)擊時,切換背景顏色。

    21個新奇漂亮的Ajax/CSS表格設(shè)計-Stripe your tables the OO way

    12. MooTools Table Row & Column highlighting

    基于MooTools 框架,高亮顯示鼠標(biāo)懸停時的單元格所在的行和列。

    21個新奇漂亮的Ajax/CSS表格設(shè)計-MooTools Table Row & Column highlighting

    13. CSS Table Gallery

    93 styled tables是一個專門收集表格樣式的站點(diǎn),下面是來自一個表格樣式的截圖:

    21個新奇漂亮的Ajax/CSS表格設(shè)計-CSS Table Gallery

    14. jQuery Table Filter

    可以對數(shù)據(jù)進(jìn)行各種不同的排序、過濾。

    21個新奇漂亮的Ajax/CSS表格設(shè)計-jQuery Table Filter

    15. Sortable/Resizable/Editable TableKit

    TableKit基于Prototype框架,專門收集各種HTML表格,可以利用Ajax實(shí)時的進(jìn)行表格欄目大小、排序等編輯。

    21個新奇漂亮的Ajax/CSS表格設(shè)計-sortable, resizable, editable

    16. Make all your tables sortable

    21個新奇漂亮的Ajax/CSS表格設(shè)計-sortable table

    17. Zebra Tables

    alistapart為我們提供了一個極好的例子,如何使用JavaScript和DOM的改變背景色風(fēng)格,以突出顯示單元格。

    21個新奇漂亮的Ajax/CSS表格設(shè)計-Zebra Tables

    18. Standardista Table Sorting

    Standardista Table Sorting 是一個Javascript模塊,讓您可以對HTML數(shù)據(jù)表的任何欄目進(jìn)行排序。

    21個新奇漂亮的Ajax/CSS表格設(shè)計-Standardista Table Sorting

    19. GridView3 Example

    21個新奇漂亮的Ajax/CSS表格設(shè)計-GridView3 Example

    20. Mootable

    21個新奇漂亮的Ajax/CSS表格設(shè)計-Mootable

    21. Drag & Drop Sortable Lists with JavaScript and CSS

    21個新奇漂亮的Ajax/CSS表格設(shè)計-Drag & Drop Sortable Lists with JavaScript and CSS

    可能還會有一些你更想尋找的詳細(xì)資料,下面是一些相關(guān)的資源鏈接:

    如果你知道其它更強(qiáng)大的Ajax/CSS表格,歡迎在此留言。

    posted @ 2008-01-23 17:46 比特鼠 閱讀(3200) | 評論 (0)編輯 收藏

    一個在線調(diào)色工具
    posted @ 2008-01-23 17:44 比特鼠 閱讀(392) | 評論 (1)編輯 收藏

    /**
     * 加碼解碼工具
     * @author lwm
     *
     */

    public class Encode {
     
     /*
      * 對應(yīng)javascript的escape()函數(shù), 加碼后的串可直接使用javascript的unescape()進(jìn)行解碼
      */
     public static String escape(String src) {
      int i;
      char j;
      StringBuffer tmp = new StringBuffer();
      tmp.ensureCapacity(src.length() * 6);
      for (i = 0; i < src.length(); i++) {
       j = src.charAt(i);
       if (Character.isDigit(j) || Character.isLowerCase(j)
         || Character.isUpperCase(j))
        tmp.append(j);
       else if (j < 256) {
        tmp.append("%");
        if (j < 16)
         tmp.append("0");
        tmp.append(Integer.toString(j, 16));
       } else {
        tmp.append("%u");
        tmp.append(Integer.toString(j, 16));
       }
      }
      return tmp.toString();
     }

     /*
      * 對應(yīng)javascript的unescape()函數(shù), 可對javascript的escape()進(jìn)行解碼
      */
     public static String unescape(String src) {
      StringBuffer tmp = new StringBuffer();
      tmp.ensureCapacity(src.length());
      int lastPos = 0, pos = 0;
      char ch;
      while (lastPos < src.length()) {
       pos = src.indexOf("%", lastPos);
       if (pos == lastPos) {
        if (src.charAt(pos + 1) == 'u') {
         ch = (char) Integer.parseInt(src
           .substring(pos + 2, pos + 6), 16);
         tmp.append(ch);
         lastPos = pos + 6;
        } else {
         ch = (char) Integer.parseInt(src
           .substring(pos + 1, pos + 3), 16);
         tmp.append(ch);
         lastPos = pos + 3;
        }
       } else {
        if (pos == -1) {
         tmp.append(src.substring(lastPos));
         lastPos = src.length();
        } else {
         tmp.append(src.substring(lastPos, pos));
         lastPos = pos;
        }
       }
      }
      return tmp.toString();
     }

    }

    posted @ 2008-01-11 17:08 比特鼠 閱讀(1837) | 評論 (0)編輯 收藏

    讀 YUI ,EXT等源碼的時候看JS天旋地轉(zhuǎn),那可不是51JS上那種挪挪位置就能理解的,此刻如果沒有JavaScrip的基礎(chǔ),更是像沒有星光的黑夜…….

    自以為覺得Js對象是很好理解的東東,然而真實(shí)踐起來卻一片糊涂。
    通過查閱經(jīng)典書籍《Professional JavaScript For Web Developers》稍微有些理解了

    JavaScript的基本類型
    原始類型如: Undefined Null Boolean Number String 等 用 typeof方法能辨別之
    引用類型如: Object Function Array Boolean Number String Date等,用insanceof方法辨別之

    嚴(yán)格來講,JavaScript沒有對象(Object),但是由于和OO術(shù)語對應(yīng),所以也稱之為對象。所以Array,Function,基本類型,引用類型,函數(shù),以及函數(shù)的屬性 等等這些都是對象。

    而對象分類,則可以分為內(nèi)置對象(Built-in Object) 和宿主對象(host object)。
    內(nèi)置對象如 Math,Data啊。
    宿主對象則如 BOM,DOM之類.

    重新回顧了下這些基本概念之后,在做簡單實(shí)踐就有些理解了。
    因此對象的使用,創(chuàng)建方式不盡相同,最簡單的歸類如下:

    1 基本創(chuàng)建方式

    function Class() {
    window.alert("Hello Class!");
    }
    var clz= new Class();

    2 訪問對象成員

    function Class(){
    this.x = " this is x";
    this.y = "this is y";
    this.z = viewXY;
    function viewXY(){
    alert("x+","+y);
    }
    }
    var clz= new Class();
    clz.viewXY();

    3 對象繼承

    function Parent() {
    this.type= "human!";
    }
    function Child(){
    this.age = "26";
    this.sex ="male";
    this.say= myInfo;
    function myInfo(msg){
    alert(msg+this.type+ ","+this.age+","+this.sex);
    }
    }
    Child.prototype = new Parent();
    var clild = new Child();
    clild.say("I'm ");

    4.重用原對象 (書上的例子太好了,搬來了)

    Funcion.prototype.toString() = function(){
    return "Function code hidden";
    }
    function sayHi(){
    alert("hi");
    }
    alert(sayHi.toString());
    posted @ 2008-01-02 11:06 比特鼠 閱讀(271) | 評論 (0)編輯 收藏

    希望能做到以下幾點(diǎn):

    1. 在Java服務(wù)端架構(gòu)的設(shè)計, 選型, 方案等方面有所突破! -- 這是最主要的!
    2. 也想玩一玩Web前端的AJAX編程, RIA(富互聯(lián)網(wǎng)應(yīng)用)等等
    3. 熟悉Linux/Unix系統(tǒng)的命令行操作
    4. 在Java中跑腳本語言Python, JRuby等等
    5. 項目管理

    暫時就這么多吧!

    posted @ 2007-12-28 09:41 比特鼠 閱讀(209) | 評論 (0)編輯 收藏

    為 Ajax 安全性所提出的經(jīng)驗法則:
    1. 如果你使用身份驗證, 確定你在請求頁上檢查!
    2. 為 SQL 注入檢查。
    3. 為 JavaScript 注入檢查。
    4. 保留商務(wù)邏輯在服務(wù)器上!
    5. 不要假設(shè)每個請求是真正的!
    6. 確認(rèn)檢查數(shù)據(jù)!
    7. 審查請求的數(shù)據(jù)而且確定它是正確的。
    posted @ 2007-12-19 17:10 比特鼠 閱讀(280) | 評論 (0)編輯 收藏

    1. jvm內(nèi)部分為主工作區(qū)和線程工作區(qū)。主工作區(qū)是實(shí)例的所有線程共有,線程工作區(qū)是實(shí)例的每個線程專有的工作區(qū),其中包括一些主工作區(qū)的一些實(shí)例字段數(shù)據(jù)的拷貝。

    2. 服務(wù)器一般都有線程池,線程資源是可以重復(fù)利用的。你2000個用戶在線,不見得能又200個用戶同時(或者說并發(fā))訪問。再說,只要對象不是太大,我寧愿用200個拷貝,也不想讓用戶在這個200個任務(wù)的隊列里等待。

    3. 兩個DB之間的復(fù)制數(shù)據(jù),每個DB各自使用自己的Sequane來生成id。復(fù)制數(shù)據(jù)時,如果DB中的外鍵是由DB維護(hù)的,則不會產(chǎn)生id沖突,如果外鍵是由外部程序維護(hù)的,則可能會產(chǎn)生錯誤!

    4. 對于非static的類的數(shù)據(jù)成員來說,在該類產(chǎn)生的實(shí)例中都有一份,并且相互獨(dú)立(修改后并不影響其他實(shí)例), 但static的數(shù)據(jù)成員則變成了每個類只有一份,即在該類產(chǎn)生的所有實(shí)例共享這一個數(shù)據(jù)成員, 該數(shù)據(jù)成員的改變會影響到其他的實(shí)例. 而static的方法則是讓你不用創(chuàng)建對象及能調(diào)用這個方法.

    5. ThreadLocal的作用就是將經(jīng)常要用到的對象的引用放到屬于線程自己的一個存儲空間中,在該線程的執(zhí)行過程中,可以通過類的靜態(tài)的ThreadLocal來方便的獲取到這個對象,而不用通過參數(shù)的形式傳來傳去。
    posted @ 2007-12-19 14:54 比特鼠 閱讀(255) | 評論 (0)編輯 收藏

    很多高分辨率的圖像真的能夠扮靚一個Web網(wǎng)站。但是它們也可能會降低網(wǎng)站的(響應(yīng))速度——圖像都是文件,文件就要占用帶寬,而帶寬與等待時間直接相關(guān)?,F(xiàn)在是你進(jìn)行自我學(xué)習(xí),了解如何利用一種叫做圖像預(yù)加載的小技巧給網(wǎng)站提速的時候了。

    圖像的預(yù)加載

           瀏覽器通常的工作方式是:只有當(dāng)要求加載圖像的HTTP請求被發(fā)送的時候,圖像才會被加載,而不論它是被動地通過<img>標(biāo)記加載,還是主動地通過方法調(diào)用加載。所以,如果你有一段JavaScript,需要在鼠標(biāo)懸停的時候切換圖像,或者在超時之后自動地更換圖像,那么你就可能會在從服務(wù)器取回圖像的時候隨時碰到等待,時間會從數(shù)秒鐘到幾分鐘不等。當(dāng)你以較慢的速度連接到Internet上的時候,或者被取回的圖像非常巨大的時候,這種狀況尤其顯著,而這種數(shù)據(jù)延遲通常都會毀掉你所期望的效果。

            有些瀏覽器會試圖轉(zhuǎn)嫁這一問題,比如把圖像保存在本地緩沖區(qū)里,這樣以后對它的調(diào)用就能夠很快進(jìn)行了,但是需要第一次調(diào)用圖像的時候仍然會產(chǎn)生延遲。預(yù)加載是一項在需要圖像之前就把它下載到緩沖區(qū)里的技術(shù)。通過這種方式,當(dāng)真的需要圖像的時候,它可以被從緩沖區(qū)里取出來,并立即顯示出來。

    Image()對象
            預(yù)加載圖像最簡單的方法用JavaScript將一個新的Image()對象實(shí)例化,并把你想要預(yù)加載的圖像的URL傳遞給它。假設(shè)我們有一個叫做
    http://www.host01.com/Get/jsp/00040004/heavyimagefile.jpg的圖像,我們希望,當(dāng)用戶把鼠標(biāo)放在一個已經(jīng)顯示過的圖像上的時,系統(tǒng)能夠顯示出這個圖像。為了預(yù)加載這個圖像,以便實(shí)現(xiàn)更快的響應(yīng)時間,我們只用創(chuàng)建一個新的Image()對象,將其命名為heavyImage,并使用onLoad()事件處理程序把它同時加載到頁面上。

    1 < html >< head >< script  language  = "JavaScript" > function  preloader()  {heavyImage  =   new  Image(); heavyImage.src = " http://www.host01.com/Get/jsp/00040004/heavyimagefile.jpg " ;} </ script ></ head >< body  onLoad ="javascript:preloader()" >< href ="#"  onMouseOver ="javascript:document.img01.src='http://www.host01.com/Get/jsp/00040004/heavyimagefile.jpg'" >< img  name ="img01"  src =http://www.host01.com/Get/jsp/00040004/"justanotherfile.jpg" ></ a ></ body ></ html >
    2

     

              要注意的是,圖像標(biāo)記自身并不會處理onMouseOver()和onMouseOut()事件,這就是為什么上面例子里的<img>標(biāo)記被放在一個<a>標(biāo)記里,后者的確加入了對這些事件類型的支持。
    用數(shù)組加載多個圖像


               在實(shí)際操作中,你可能需要預(yù)加載一幅以上的圖像;例如,在包含有多個圖像翻滾(rollover)的菜單條里,或者如果你正在嘗試創(chuàng)建平滑的動態(tài)效果。這并不困難;你所需要做的就是使用JavaScript的數(shù)組,就像下面例子里的一樣:

     

    1 < script language = " JavaScript " > function  preloader()  //  counter var i = 0; // create object imageObj = new Image(); // set image list images = new Array(); images[0]="image1.jpg" images[1]="image2.jpg" images[2]="image3.jpg" images[3]="image4.jpg" // start preloading for(i=0; i<=3; i++) { imageObj.src=images[i]; }
    2 }
      </ script >


             在上面的例子里,你先定義變量i和叫做imageObj的Image()對象。然后定義一個叫做images[]的新數(shù)組,在這個數(shù)組里,每個數(shù)組元素都保存著需要預(yù)加載的圖像來源。最后,創(chuàng)建一個for()循環(huán),讓它在數(shù)組里循環(huán),并將它們中的每一個都指派給Image()對象,這樣就能夠把它預(yù)加載到緩沖區(qū)里。
    onLoad()事件處理程序
            就和JavaScript里的其它很多對象一樣,Image()對象也帶有多個事件處理程序。這其中最有用的毫無疑問的就是onLoad()處理程序了,它會在完成圖像加載的時候被調(diào)用。這個處理程序可以與自定義的函數(shù)一起使用,以便在完成圖像加載之后進(jìn)行特定的任務(wù)。下面的例子通過在圖像加載的時候顯示“請等待(please wait)”提示信息來說明這個問題,然后在圖像完成加載之后就向瀏覽器發(fā)送一個新的URL。

     

    < html >< head >< script  language ="JavaScript" > //  create an image objectobjImage = new Image(); // set what happens once the image has loaded objImage.onLoad=imagesLoaded(); // preload the image fileobjImage.src='http://www.host01.com/Get/jsp/00040004/images/image1n.gif';// function invoked on image loadfunction imagesLoaded(){ document.location.href='index2.html';}</script></head><body>Please wait, loading images</body></html>

     


           當(dāng)然,你還可以創(chuàng)建一個圖像數(shù)組,對它進(jìn)行循環(huán),預(yù)加載每個圖像,并在每個階段對已加載圖像的數(shù)量保持跟蹤。一旦加載了所有的圖像,事件處理程序就能夠按照設(shè)定把瀏覽器帶到下一個頁面(或者進(jìn)行其他的任務(wù))。

    預(yù)加載與多狀態(tài)菜單

              現(xiàn)在,把你剛剛學(xué)到的理論付諸真正的實(shí)踐怎么樣?下面一部分內(nèi)容就是我碰巧編寫的一段代碼——一個由多個按鈕(圖像鏈接)組成的菜單條——其中每個按鈕都可能處于三種狀態(tài)中的一種:正常(normal)、hover(懸停)和點(diǎn)擊(click)。由于所有的按鈕都有多個狀態(tài),所以就有必要使用圖像預(yù)加載來確保菜單能夠根據(jù)其切換到的狀態(tài)進(jìn)行快速的響應(yīng)。列表A里的代碼就說了這一點(diǎn)。

               列表A里的HTML代碼會建立一個由四個按鈕組成的菜單條,每個按鈕都有三種狀態(tài):正常、懸停和點(diǎn)擊。其要求如下:

              但鼠標(biāo)移動到處于正常狀態(tài)的按鈕上時,按鈕會變?yōu)閼彝顟B(tài)。當(dāng)鼠標(biāo)移開的時候,按鈕又會恢復(fù)到正常狀態(tài)。當(dāng)鼠標(biāo)點(diǎn)擊按鈕的時候,按鈕就會變?yōu)辄c(diǎn)擊狀態(tài)。它會一直保持這個狀態(tài),直到另外一個按鈕被點(diǎn)擊。如果有一個按鈕被點(diǎn)擊,那么其他的按鈕就都不能處于點(diǎn)擊狀態(tài)。其他的按鈕只能夠處于懸?;蛘哒顟B(tài)。一次只能有一個按鈕可以被點(diǎn)擊。一次只能有一個按鈕處于懸停狀態(tài)。
            第一項任務(wù)是建立保存有菜單每個狀態(tài)的圖像的數(shù)組。與這些數(shù)組元素相對應(yīng)的<img>元素也都在HTML文檔的主體里被創(chuàng)建,并按順序命名。要注意的是,對數(shù)組值的索引是從0開始的,而相應(yīng)的<img>元素是從1開始命名的——這就需要在腳本后面的一段里進(jìn)行某種計算上的調(diào)整。

            PreloadImages()函數(shù)會負(fù)責(zé)把所有的圖像都加載到緩沖區(qū)里,這樣的話對鼠標(biāo)移動的響應(yīng)時間會被減到最小。一個for()循環(huán)被用在第一步里創(chuàng)建的圖像里進(jìn)行迭代,并預(yù)加載每一個圖像。

                ResetAll()函數(shù)是把所有圖像恢復(fù)都到它們正常狀態(tài)的方便方法。這是有必要的,因為當(dāng)菜單的項目被點(diǎn)擊的時候,菜單里其他所有的項目都必須在被點(diǎn)擊項目能夠切換到點(diǎn)擊狀態(tài)之前恢復(fù)到正常狀態(tài)。

            SetNormal()、setHover()和setClick()函數(shù)負(fù)責(zé)把特定圖像(圖像的編號被作為函數(shù)的自變量進(jìn)行傳遞)的來源分別改為正常、懸?;蛘唿c(diǎn)擊狀態(tài)。由于被點(diǎn)擊的圖像必須一直保持點(diǎn)擊狀態(tài),直到另外一個圖像被點(diǎn)擊(見第二項要求),所以它們暫時不會對鼠標(biāo)移動作出反應(yīng);這樣的話,如果按鈕還不是處在點(diǎn)擊狀態(tài),那么setNormal()和setHover()函數(shù)所包括的代碼就只能用來改變按鈕的狀態(tài)。

             上面所提到的預(yù)加載只是提高你JavaScript效果響應(yīng)時間的多種方法之一。就在你的網(wǎng)站上使用上面列出的技巧,并根據(jù)你的要求在需要的地方更改它們吧。祝你好運(yùn)!

    posted @ 2007-12-19 10:40 比特鼠 閱讀(254) | 評論 (0)編輯 收藏

    這些東西都是Java Script大部分都是由老外寫的,并且封裝得很好,在運(yùn)用上也很方便,而且也都兼容FF與OPERA,檔案中少部分是由中國的高手寫的。

     

      一、多樣化摺疊菜單:下載

      一個由老外寫的折疊式垂直菜單,多樣化,多功能,可自訂,使用容易,支持FF。

    國內(nèi)外 Java Script 經(jīng)典封裝
    圖1

      二、CSS圓角邊框:下載

      以CSS為主要,用Java Script封裝的相當(dāng)完整,也是老外寫的,支持多瀏覽器,可以自訂樣式,目前有十多種可以運(yùn)用。

    國內(nèi)外 Java Script 經(jīng)典封裝
    圖2

    國內(nèi)外 Java Script 經(jīng)典封裝
    圖3

      三、模擬視窗:下載

      用層模擬的視窗,是一個中國高手寫的,Java Script封裝的相當(dāng)好,使用上也很容易

    國內(nèi)外 Java Script 經(jīng)典封裝
    圖4
      

      四、支持FF的省略符:下載

      說到省略符,那非CSS莫屬,有個老外用Java Script來實(shí)現(xiàn),并且是批量處理的,重點(diǎn)是支持FF。

    國內(nèi)外 Java Script 經(jīng)典封裝
    圖5

      五、TAB選項卡:下載

      用Java Script模仿各種作業(yè)系統(tǒng)的選項卡,老外就是牛,不僅支援多樣式的即時切換,同時也支援每個選項卡是否附帶圖示的切換選項,選項卡也可以上下切換。

    國內(nèi)外 Java Script 經(jīng)典封裝
    圖6
      

      六、最佳化多樣式Windows:下載

      用層模擬視窗的最佳代表作,這是我看過功能最多的模擬式窗,內(nèi)附多達(dá)74項功能與樣式,你完完全全可以把它當(dāng)成是一個真正的視窗來應(yīng)用,可以根據(jù)你的需求來應(yīng)用,快丟掉你那認(rèn)為好用的層視窗,這套封裝非常完整的視窗絕對可以滿足你的各種需求。

    國內(nèi)外 Java Script 經(jīng)典封裝
    圖7

    國內(nèi)外 Java Script 經(jīng)典封裝
    圖8

      七、多樣化的垂直菜單:附件

      別具風(fēng)格的方塊式垂直折疊菜單,目前有8種風(fēng)格可以運(yùn)用,如果你已經(jīng)厭煩WEB上平凡的菜單,這套在國外頗受歡迎的菜單肯定是你的最佳首選。

    國內(nèi)外 Java Script 經(jīng)典封裝
    圖9
      

      八、多樣化的連結(jié)提示效果:下載

      這個連結(jié)提示樣式允許你直接寫入css與html,共有14項功能可以讓你自訂。

    國內(nèi)外 Java Script 經(jīng)典封裝
    圖10

      九、側(cè)欄式折疊菜單:下載

      這是一個側(cè)欄式的折疊菜單,它允許你設(shè)置它是否有過渡效果、側(cè)欄菜單是否自動伸縮、菜單項切換是否允許動畫過渡、是否輪替切換等多項設(shè)置,并且也有多種樣式可以運(yùn)用。

      這個腳本有個很好玩的東東,下載并且解壓後,請進(jìn)入samples的目錄并打show.html看看效果,我不知道這效果容不容易實(shí)現(xiàn),但是這效果很牛,菜單全自動運(yùn)行的~

    國內(nèi)外 Java Script 經(jīng)典封裝
    圖11
      

      十、圖形滾動條:下載

      老外寫的圖形滾動條,有多種樣式,在ie里頭還支持滾輪滾動。

    國內(nèi)外 Java Script 經(jīng)典封裝
    圖12

      十一、圖片倒影效果:下載
      說到圖片倒影,不外乎就是直接作成圖片跟css濾鏡來實(shí)現(xiàn),但是這個是用Java Script實(shí)現(xiàn)的,值得借鏡。

    國內(nèi)外 Java Script 經(jīng)典封裝
    圖13

      十二、代碼自動高亮:下載

      雖說這不是什麼新東西,但總是會有人需要吧,而且想學(xué)正則表達(dá)的人,這肯定是最佳借鏡的作品。

    國內(nèi)外 Java Script 經(jīng)典封裝
    圖14
      
      

      十三、酷似flash效果的圖片展示:下載

      這個老外牛到有點(diǎn)變態(tài),這圖片展示效果已經(jīng)跟FLASH沒什麼兩樣,用Java Script寫的耶。

    國內(nèi)外 Java Script 經(jīng)典封裝
    圖15

      十四、讓ie6支援png圖檔:下載

    國內(nèi)外 Java Script 經(jīng)典封裝
    圖16

      這個問題之前被很多人討論過,我就不多說什麼了,有需要下吧。

    posted @ 2007-12-13 17:29 比特鼠 閱讀(5341) | 評論 (5)編輯 收藏

    在一個老外的Blog上看到了這個網(wǎng)站,發(fā)現(xiàn)原來是一個以C語言為基準(zhǔn)的性能比較網(wǎng)站!

    Java還算不錯,Ruby就不怎么樣了, 在腳本語言中居然排在了最后!

    看來,解析性的語言玩起來是簡單方便了,可是卻是以損失性能為代價的!
    posted @ 2007-12-13 16:34 比特鼠 閱讀(468) | 評論 (0)編輯 收藏

    BIG-ENDIAN(大字節(jié)序、高字節(jié)序)
    LITTLE-ENDIAN(小字節(jié)序、低字節(jié)序)
    主機(jī)字節(jié)序
    網(wǎng)絡(luò)字節(jié)順序
    JAVA字節(jié)序

    1.BIG-ENDIAN、LITTLE-ENDIAN跟多字節(jié)類型的數(shù)據(jù)有關(guān)的比如int,short,long型,而對單字節(jié)數(shù)據(jù)byte卻沒有影響。BIG-ENDIAN就是低位字節(jié)排放在內(nèi)存的低端,高位字節(jié)排放在內(nèi)存的高端。而LITTLE-ENDIAN正好相反。
    比如 int a = 0x05060708
    在BIG-ENDIAN的情況下存放為:
    字節(jié)號 0 1 2 3
    數(shù)據(jù) 05 06 07 08
    在LITTLE-ENDIAN的情況下存放為:
    字節(jié)號 0 1 2 3
    數(shù)據(jù) 08 07 06 05

    2.BIG-ENDIAN、LITTLE-ENDIAN、跟CPU有關(guān)的,每一種CPU不是BIG-ENDIAN就是LITTLE-ENDIAN、。IA架構(gòu)的CPU中是Little-Endian,而PowerPC 、SPARC和Motorola處理器。這其實(shí)就是所謂的主機(jī)字節(jié)序。而網(wǎng)絡(luò)字節(jié)序是指數(shù)據(jù)在網(wǎng)絡(luò)上傳輸時是大頭還是小頭的,在Internet的網(wǎng)絡(luò)字節(jié)序是BIG-ENDIAN。所謂的JAVA字節(jié)序指的是在JAVA虛擬機(jī)中多字節(jié)類型數(shù)據(jù)的存放順序,JAVA字節(jié)序也是BIG-ENDIAN。

    3.所以在用C/C++寫通信程序時,在發(fā)送數(shù)據(jù)前務(wù)必用htonl和htons去把整型和短整型的數(shù)據(jù)進(jìn)行從主機(jī)字節(jié)序到網(wǎng)絡(luò)字節(jié)序的轉(zhuǎn)換,而接收數(shù)據(jù)后對于整型和短整型數(shù)據(jù)則必須調(diào)用ntohl和ntohs實(shí)現(xiàn)從網(wǎng)絡(luò)字節(jié)序到主機(jī)字節(jié)序的轉(zhuǎn)換。如果通信的一方是JAVA程序、一方是C/C++程序時,則需要在C/C++一側(cè)使用以上幾個方法進(jìn)行字節(jié)序的轉(zhuǎn)換,而JAVA一側(cè),則不需要做任何處理,因為JAVA字節(jié)序與網(wǎng)絡(luò)字節(jié)序都是BIG-ENDIAN,只要C/C++一側(cè)能正確進(jìn)行轉(zhuǎn)換即可(發(fā)送前從主機(jī)序到網(wǎng)絡(luò)序,接收時反變換)。如果通信的雙方都是JAVA,則根本不用考慮字節(jié)序的問題了。

    4.如果網(wǎng)絡(luò)上全部是PowerPC,SPARC和Motorola CPU的主機(jī)那么不會出現(xiàn)任何問題,但由于實(shí)際存在大量的IA架構(gòu)的CPU,所以經(jīng)常出現(xiàn)數(shù)據(jù)傳輸錯誤。

    5.文章開頭所提出的問題,就是因為程序運(yùn)行在X86架構(gòu)的PC SERVER上,發(fā)送數(shù)據(jù)的一端用C實(shí)現(xiàn)的,接收一端是用JAVA實(shí)現(xiàn)的,而發(fā)送端在發(fā)送數(shù)據(jù)前未進(jìn)行從主機(jī)字節(jié)序到網(wǎng)絡(luò)字節(jié)序的轉(zhuǎn)換,這樣接收端接收到的是LITTLE-ENDIAN的數(shù)據(jù),數(shù)據(jù)解釋自然出錯。
    具體數(shù)據(jù)如下,實(shí)際發(fā)送的數(shù)據(jù)為23578
    發(fā)送端發(fā)送數(shù)據(jù): 1A 5C
    接收端接收到數(shù)據(jù)后,按BIG-ENDIAN進(jìn)行解釋具體數(shù)據(jù)是多少?你們自己去計算并比較吧!


    ===============================================================================================

    Big Endian and Little Endian

        談到字節(jié)序的問題,必然牽涉到兩大CPU派系。那就是Motorola的PowerPC系列CPU和Intel的x86系列CPU。PowerPC系列采用big endian方式存儲數(shù)據(jù),而x86系列則采用little endian方式存儲數(shù)據(jù)。那么究竟什么是big endian,什么又是little endian呢?

        其實(shí)big endian是指低地址存放最高有效字節(jié)(MSB),而little endian則是低地址存放最低有效字節(jié)(LSB),即常說的低位在先,高位在后。
        用文字說明可能比較抽象,下面用圖像加以說明。比如數(shù)字0x12345678在兩種不同字節(jié)序CPU中的存儲順序如下所示:

    Big Endian

      低地址                           高地址
      ----------------------------------------->
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |     12     |      34    |     56      |     78    |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

    Little Endian

      低地址                           高地址
      ----------------------------------------->
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |     78     |      56    |     34      |     12    |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

        從上面兩圖可以看出,采用big endian方式存儲數(shù)據(jù)是符合我們?nèi)祟惖乃季S習(xí)慣的。而little endian,!@#$%^&*,見鬼去吧 -_-|||

        為什么要注意字節(jié)序的問題呢?你可能這么問。當(dāng)然,如果你寫的程序只在單機(jī)環(huán)境下面運(yùn)行,并且不和別人的程序打交道,那么你完全可以忽略字節(jié)序的存在。但是,如果你的程序要跟別人的程序產(chǎn)生交互呢?尤其是當(dāng)你把你在微機(jī)上運(yùn)算的結(jié)果運(yùn)用到計算機(jī)群上去的話。在這里我想說說兩種語言。C/C++語言編寫的程序里數(shù)據(jù)存儲順序是跟編譯平臺所在的CPU相關(guān)的,而JAVA編寫的程序則唯一采用big endian方式來存儲數(shù)據(jù)。試想,如果你用C/C++語言在x86平臺下編寫的程序跟別人的JAVA程序互通時會產(chǎn)生什么結(jié)果?就拿上面的 0x12345678來說,你的程序傳遞給別人的一個數(shù)據(jù),將指向0x12345678的指針傳給了JAVA程序,由于JAVA采取big endian方式存儲數(shù)據(jù),很自然的它會將你的數(shù)據(jù)翻譯為0x78563412。什么?竟然變成另外一個數(shù)字了?是的,就是這種后果。因此,在你的C程序傳給JAVA程序之前有必要進(jìn)行字節(jié)序的轉(zhuǎn)換工作。

        無獨(dú)有偶,所有網(wǎng)絡(luò)協(xié)議也都是采用big endian的方式來傳輸數(shù)據(jù)的。所以有時我們也會把big endian方式稱之為網(wǎng)絡(luò)字節(jié)序。當(dāng)兩臺采用不同字節(jié)序的主機(jī)通信時,在發(fā)送數(shù)據(jù)之前都必須經(jīng)過字節(jié)序的轉(zhuǎn)換成為網(wǎng)絡(luò)字節(jié)序后再進(jìn)行傳輸。ANSI C中提供了四個轉(zhuǎn)換字節(jié)序的宏。


    ========================================================================================================

    /**
    * 通信格式轉(zhuǎn)換
    *
    * Java和一些windows編程語言如c、c++、delphi所寫的網(wǎng)絡(luò)程序進(jìn)行通訊時,需要進(jìn)行相應(yīng)的轉(zhuǎn)換
    * 高、低字節(jié)之間的轉(zhuǎn)換
    * windows的字節(jié)序為低字節(jié)開頭
    * linux,unix的字節(jié)序為高字節(jié)開頭
    * java則無論平臺變化,都是高字節(jié)開頭
    */

    public class FormatTransfer {
    /**
      * 將int轉(zhuǎn)為低字節(jié)在前,高字節(jié)在后的byte數(shù)組
      * @param n int
      * @return byte[]
      */
    public static byte[] toLH(int n) {
      byte[] b = new byte[4];
      b[0] = (byte) (n & 0xff);
      b[1] = (byte) (n >> 8 & 0xff);
      b[2] = (byte) (n >> 16 & 0xff);
      b[3] = (byte) (n >> 24 & 0xff);
      return b;
    }

    /**
      * 將int轉(zhuǎn)為高字節(jié)在前,低字節(jié)在后的byte數(shù)組
      * @param n int
      * @return byte[]
      */
    public static byte[] toHH(int n) {
      byte[] b = new byte[4];
      b[3] = (byte) (n & 0xff);
      b[2] = (byte) (n >> 8 & 0xff);
      b[1] = (byte) (n >> 16 & 0xff);
      b[0] = (byte) (n >> 24 & 0xff);
      return b;
    }

    /**
      * 將short轉(zhuǎn)為低字節(jié)在前,高字節(jié)在后的byte數(shù)組
      * @param n short
      * @return byte[]
      */
    public static byte[] toLH(short n) {
      byte[] b = new byte[2];
      b[0] = (byte) (n & 0xff);
      b[1] = (byte) (n >> 8 & 0xff);
      return b;
    }

    /**
      * 將short轉(zhuǎn)為高字節(jié)在前,低字節(jié)在后的byte數(shù)組
      * @param n short
      * @return byte[]
      */
    public static byte[] toHH(short n) {
      byte[] b = new byte[2];
      b[1] = (byte) (n & 0xff);
      b[0] = (byte) (n >> 8 & 0xff);
      return b;
    }

     

    /**
      * 將將int轉(zhuǎn)為高字節(jié)在前,低字節(jié)在后的byte數(shù)組

    public static byte[] toHH(int number) {
      int temp = number;
      byte[] b = new byte[4];
      for (int i = b.length - 1; i > -1; i--) {
        b = new Integer(temp & 0xff).byteValue();
        temp = temp >> 8;
      }
      return b;
    }

    public static byte[] IntToByteArray(int i) {
        byte[] abyte0 = new byte[4];
        abyte0[3] = (byte) (0xff & i);
        abyte0[2] = (byte) ((0xff00 & i) >> 8);
        abyte0[1] = (byte) ((0xff0000 & i) >> 16);
        abyte0[0] = (byte) ((0xff000000 & i) >> 24);
        return abyte0;
    }


    */

    /**
      * 將float轉(zhuǎn)為低字節(jié)在前,高字節(jié)在后的byte數(shù)組
      */
    public static byte[] toLH(float f) {
      return toLH(Float.floatToRawIntBits(f));
    }

    /**
      * 將float轉(zhuǎn)為高字節(jié)在前,低字節(jié)在后的byte數(shù)組
      */
    public static byte[] toHH(float f) {
      return toHH(Float.floatToRawIntBits(f));
    }

    /**
      * 將String轉(zhuǎn)為byte數(shù)組
      */
    public static byte[] stringToBytes(String s, int length) {
      while (s.getBytes().length < length) {
        s += " ";
      }
      return s.getBytes();
    }


    /**
      * 將字節(jié)數(shù)組轉(zhuǎn)換為String
      * @param b byte[]
      * @return String
      */
    public static String bytesToString(byte[] b) {
      StringBuffer result = new StringBuffer("");
      int length = b.length;
      for (int i=0; i<length; i++) {
        result.append((char)(b & 0xff));
      }
      return result.toString();
    }

    /**
      * 將字符串轉(zhuǎn)換為byte數(shù)組
      * @param s String
      * @return byte[]
      */
    public static byte[] stringToBytes(String s) {
      return s.getBytes();
    }

    /**
      * 將高字節(jié)數(shù)組轉(zhuǎn)換為int
      * @param b byte[]
      * @return int
      */
    public static int hBytesToInt(byte[] b) {
      int s = 0;
      for (int i = 0; i < 3; i++) {
        if (b >= 0) {
        s = s + b;
        } else {
        s = s + 256 + b;
        }
        s = s * 256;
      }
      if (b[3] >= 0) {
        s = s + b[3];
      } else {
        s = s + 256 + b[3];
      }
      return s;
    }

    /**
      * 將低字節(jié)數(shù)組轉(zhuǎn)換為int
      * @param b byte[]
      * @return int
      */
    public static int lBytesToInt(byte[] b) {
      int s = 0;
      for (int i = 0; i < 3; i++) {
        if (b[3-i] >= 0) {
        s = s + b[3-i];
        } else {
        s = s + 256 + b[3-i];
        }
        s = s * 256;
      }
      if (b[0] >= 0) {
        s = s + b[0];
      } else {
        s = s + 256 + b[0];
      }
      return s;
    }


    /**
      * 高字節(jié)數(shù)組到short的轉(zhuǎn)換
      * @param b byte[]
      * @return short
      */
    public static short hBytesToShort(byte[] b) {
      int s = 0;
      if (b[0] >= 0) {
        s = s + b[0];
        } else {
        s = s + 256 + b[0];
        }
        s = s * 256;
      if (b[1] >= 0) {
        s = s + b[1];
      } else {
        s = s + 256 + b[1];
      }
      short result = (short)s;
      return result;
    }

    /**
      * 低字節(jié)數(shù)組到short的轉(zhuǎn)換
      * @param b byte[]
      * @return short
      */
    public static short lBytesToShort(byte[] b) {
      int s = 0;
      if (b[1] >= 0) {
        s = s + b[1];
        } else {
        s = s + 256 + b[1];
        }
        s = s * 256;
      if (b[0] >= 0) {
        s = s + b[0];
      } else {
        s = s + 256 + b[0];
      }
      short result = (short)s;
      return result;
    }

    /**
      * 高字節(jié)數(shù)組轉(zhuǎn)換為float
      * @param b byte[]
      * @return float
      */
    public static float hBytesToFloat(byte[] b) {
      int i = 0;
      Float F = new Float(0.0);
      i = ((((b[0]&0xff)<<8 | (b[1]&0xff))<<8) | (b[2]&0xff))<<8 | (b[3]&0xff);
      return F.intBitsToFloat(i);
    }

    /**
      * 低字節(jié)數(shù)組轉(zhuǎn)換為float
      * @param b byte[]
      * @return float
      */
    public static float lBytesToFloat(byte[] b) {
      int i = 0;
      Float F = new Float(0.0);
      i = ((((b[3]&0xff)<<8 | (b[2]&0xff))<<8) | (b[1]&0xff))<<8 | (b[0]&0xff);
      return F.intBitsToFloat(i);
    }

    /**
      * 將byte數(shù)組中的元素倒序排列
      */
    public static byte[] bytesReverseOrder(byte[] b) {
      int length = b.length;
      byte[] result = new byte[length];
      for(int i=0; i<length; i++) {
        result[length-i-1] = b;
      }
      return result;
    }

    /**
      * 打印byte數(shù)組
      */
    public static void printBytes(byte[] bb) {
      int length = bb.length;
      for (int i=0; i<length; i++) {
        System.out.print(bb + " ");
      }
      System.out.println("");
    }

    public static void logBytes(byte[] bb) {
      int length = bb.length;
      String ut = "";
      for (int i=0; i<length; i++) {
        ut = out + bb + " ";
      }

    }

    /**
      * 將int類型的值轉(zhuǎn)換為字節(jié)序顛倒過來對應(yīng)的int值
      * @param i int
      * @return int
      */
    public static int reverseInt(int i) {
      int result = FormatTransfer.hBytesToInt(FormatTransfer.toLH(i));
      return result;
    }

    /**
      * 將short類型的值轉(zhuǎn)換為字節(jié)序顛倒過來對應(yīng)的short值
      * @param s short
      * @return short
      */
    public static short reverseShort(short s) {
      short result = FormatTransfer.hBytesToShort(FormatTransfer.toLH(s));
      return result;
    }

    /**
      * 將float類型的值轉(zhuǎn)換為字節(jié)序顛倒過來對應(yīng)的float值
      * @param f float
      * @return float
      */
    public static float reverseFloat(float f) {
      float result = FormatTransfer.hBytesToFloat(FormatTransfer.toLH(f));
      return result;
    }

    }

    posted @ 2007-10-24 09:57 比特鼠 閱讀(3406) | 評論 (0)編輯 收藏

    實(shí)現(xiàn)Leader/Fellows模式的項目--CAJ, 地址是:http://caj.cosylab.com/
    posted @ 2007-10-23 14:57 比特鼠 閱讀(198) | 評論 (0)編輯 收藏

    網(wǎng)址:http://httpd.apache.org/docs/2.0/programs/ab.html
    posted @ 2007-10-23 14:53 比特鼠 閱讀(273) | 評論 (0)編輯 收藏

    緩沖區(qū)基礎(chǔ)

    抽象類Buffer是java.nio包支持緩沖區(qū)的基礎(chǔ)。 Buffer 的工作方式就象內(nèi)存中用于讀寫基本數(shù)據(jù)類型的 RandomAccessFile 。象 RandomAccessFile 一樣,使用 Buffer ,所執(zhí)行的下一個操作(讀/寫)在當(dāng)前某個位置發(fā)生。執(zhí)行讀/寫操作中的任一個都會改變那個位置,所以在寫操作之后進(jìn)行讀操作不會讀到剛才所寫的內(nèi)容,而會讀到剛才所寫內(nèi)容之后的數(shù)據(jù)。 Buffer 提供了四個指示方法,用于訪問線性結(jié)構(gòu)(從最高值到最低值):

    capacity() :表明緩沖區(qū)的容量大小, 一旦確定了大小, 將不能再改變;
    limit() :告訴您到目前為止已經(jīng)往緩沖區(qū)填了多少字節(jié),或者讓您用 :limit(int newLimit) 來改變這個限制
    position() :告訴您當(dāng)前的位置,以執(zhí)行下一個讀/寫操作
    mark() :為了稍后用 reset() 進(jìn)行重新設(shè)置而記住某個位置
    flip() :交換限制指針和位置指針,然后將位置置為 0,并廢棄已經(jīng)做的mark標(biāo)記

    緩沖區(qū)的基本操作是讀 get() 和寫 put() ;然而,這些方法在子類中都是針對每種數(shù)據(jù)類型的特定方法。為了說明這一情況,讓我們研究一個簡單示例,該示例演示了從同一個緩沖區(qū)讀和寫一個字符。在清單 1 中, flip() 方法交換限制和位置,然后將位置置為 0,并廢棄標(biāo)記,讓您讀剛才所寫的數(shù)據(jù):


    清單 1. 讀/寫示例
    import java.nio.*;
    ...
    CharBuffer buff = ...;
    buff.put('A');
    buff.flip();
    char c = buff.get();
    System.out.println("An A: " + c);
     


    現(xiàn)在讓我們研究一些具體的 Buffer 子類。

     

    緩沖區(qū)類型

    Merlin 具有 7 種特定的 Buffer 類型,每種類型對應(yīng)著一個基本數(shù)據(jù)類型(不包括 boolean):

    ByteBuffer       //存放任何除boolean類型外的其他基本類型
    CharBuffer       //存放char
    DoubleBuffer     //存放double
    FloatBuffer      //存放float
    IntBuffer        //存放int
    LongBuffer       //存放long
    ShortBuffer      //存放short

    在本文后面,我將討論第 8 種類型 MappedByteBuffer ,它用于內(nèi)存映射文件。如果您必須使用的類型不是這些基本類型,則可以先從 ByteBuffer 獲得字節(jié)類型,然后將其轉(zhuǎn)換成 Object 或其它任何類型。


    創(chuàng)建緩沖區(qū)
    一共有兩種類型的緩沖區(qū),直接緩沖區(qū)和非直接緩沖區(qū)。

    在創(chuàng)建緩沖區(qū)時,可以要求創(chuàng)建直接緩沖區(qū),創(chuàng)建直接緩沖區(qū)的成本要比創(chuàng)建間接緩沖區(qū)高,但這可以使運(yùn)行時環(huán)境直接在該緩沖區(qū)上進(jìn)行較快的本機(jī) I/O 操作。因為創(chuàng)建直接緩沖區(qū)所增加的成本,所以直接緩沖區(qū)只用于長生存期的緩沖區(qū),而不用于短生存期、一次性且用完就丟棄的緩沖區(qū)。而且,只能在 ByteBuffer 這個級別上創(chuàng)建直接緩沖區(qū),如果希望使用其它類型,則必須將 Buffer 轉(zhuǎn)換成更具體的類型。

    判斷一個緩沖區(qū)是否是直接緩沖區(qū),可以調(diào)用isDirect()方法。

    有三種方式來獲取一個緩沖區(qū)的對象:
    a. 調(diào)用allocate()或者allocateDirect()方法直接分配,其中allocateDirect()返回的是直接緩沖區(qū)。
    b. 包裝一個數(shù)組,如:
          byte[] b = new byte[1024];
          ByteBuffer bb = ByteBuffer.wrap(b);
    c. 內(nèi)存映射,即調(diào)用FileChannel的map()方法。

    緩沖區(qū)基本屬性
    這幾個屬性是每個緩沖區(qū)都有的并且是常用的操作。
    a. 容量(capacity),緩沖區(qū)大小
    b. 限制(limit),第一個不應(yīng)被讀取或?qū)懭氲淖止?jié)的索引,總是小于容量。
    c. 位置(position),下一個被讀取或?qū)懭氲淖止?jié)的索引,總是小于限制。
    d. clear()方法:設(shè)置limit為capacity,position為0。
    e. filp()方法:設(shè)置limit為當(dāng)前position,然后設(shè)置position為0。
    f. rewind()方法:保持limit不變,設(shè)置position為0。

    緩沖區(qū)數(shù)據(jù)操作
    操作包括了讀取和寫入數(shù)據(jù)兩種。
    讀取數(shù)據(jù)使用get()及其系列方法,除boolean外,每一種類型包括了對應(yīng)的get()方法,如getInt(),getChar()等,get()方法用來讀取字節(jié),支持相對和絕對索引兩種方式。
    寫入數(shù)據(jù)使用put()及其系列方法,和get()方法是對應(yīng)的。

    package nio;

    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.nio.ByteBuffer;
    import java.nio.channels.FileChannel;

    public class BufferDemo ...{

        
        public static void main(String[] args) throws Exception...{
            //分配一個非直接緩沖區(qū)
            ByteBuffer bb = ByteBuffer.allocate(100);
            //向緩沖區(qū)寫入0到100的字節(jié)制
            for(int i = 0; i <100; i++)...{
                byte b = (byte) (Math.random() * 100);
                bb.put(b);
            }
            
            System.out.println("寫入文件前的緩沖區(qū)數(shù)據(jù)");
            bb.flip();
            while(bb.hasRemaining())
                System.out.print(bb.get() + " ");
            System.out.println();
            
            //獲取一個關(guān)聯(lián)到文件buffer.txt的信道
            FileChannel fc = new FileOutputStream("buffer.txt").getChannel();
            //將緩沖區(qū)數(shù)據(jù)寫到文件中
            bb.flip();
            fc.write(bb);
            //防止緩存
            fc.force(true);
            //關(guān)閉信道
            fc.close();
            bb = null;
            fc = null;
            
            //下面從文件中讀取數(shù)據(jù)
            fc = new FileInputStream("buffer.txt").getChannel();
            ByteBuffer bb2 = ByteBuffer.allocate((int) fc.size());
            fc.read(bb2);
            System.out.println("從文件讀取的緩沖區(qū)數(shù)據(jù)");
            bb2.flip();
            while(bb2.hasRemaining())
                System.out.print(bb2.get() + " ");
            System.out.println();
            fc.close();
            bb2 = null;
            fc = null;
            

        }

    }

    內(nèi)存映射文件

    第 8 種 Buffer 類型 MappedByteBuffer 只是一種特殊的 ByteBuffer 。 MappedByteBuffer 將文件所在區(qū)域直接映射到內(nèi)存。通常,該區(qū)域包含整個文件,但也可以只映射部分文件。所以,必須指定要映射文件的哪部分。而且,與其它 Buffer 對象一樣,這里沒有構(gòu)造函數(shù);必須讓 java.nio.channels.FileChannel 的 map() 方法來獲取 MappedByteBuffer 。此外,無需過多涉及通道就可以用 getChannel() 方法從 FileInputStream 或 FileOutputStream 獲取 FileChannel 。通過從命令行傳入文件名來讀取文本文件的內(nèi)容,清單 4 顯示了 MappedByteBuffer :


    清單 4. 讀取內(nèi)存映射文本文件
    import java.io.*;
    import java.nio.*;
    import java.nio.channels.*;
    import java.nio.charset.*;
    public class ReadFileBuff {
      public static void main(String args[]) throws IOException {
         if (args.length != 0) {
          String filename = args[0];
          FileInputStream fis = new FileInputStream(filename);
          FileChannel channel = fis.getChannel();
          int length = (int)channel.size();
          MappedByteBuffer byteBuffer =
            channel.map(FileChannel.MapMode.READ_ONLY, 0, length);
          Charset charset = Charset.forName("ISO-8859-1");
          CharsetDecoder decoder = charset.newDecoder();
          CharBuffer charBuffer = decoder.decode(byteBuffer);
          for (int i=0, n=charBuffer.length(); i<n; i++) {
            System.out.print(charBuffer.get());
          }
        }
      }
    }

    posted @ 2007-08-01 11:13 比特鼠 閱讀(3826) | 評論 (0)編輯 收藏

    1. 左移操作: x << n
      x可以是byte, short, char, int, long基本類型, n(位移量)只能是int型

      編譯器的執(zhí)行步驟:
      1) 如果x是byte, short, char類型, 則將x提升為int;
      2) 如果x是byte, short, char, int類型, 則n被重新賦值(過程是:取n的補(bǔ)碼的低5位再轉(zhuǎn)成十進(jìn)制的int值,相當(dāng)對n取32模: n=n%32);
         如果x是long型, 則n被重新賦值(過程是:取n的補(bǔ)碼的低6位再轉(zhuǎn)成十進(jìn)制的int值,相當(dāng)對n取64模: n=n%64);
         (因為int類型為4個字節(jié),即32位,移動32位將沒有任何意義.對于long則是模64)
      3) 對x左移n個位數(shù), 整個表達(dá)式產(chǎn)生一個新值(x的值不變);
    2. <<是左移符號,列x<<1,就是x的內(nèi)容左移一位(x的內(nèi)容并不改變)
    3. >>是帶符號位的右移符號,x>>1就是x的內(nèi)容右移一位,如果開頭是1則補(bǔ)1,是0責(zé)補(bǔ)0,(x的內(nèi)容并不改變).
    4. >>>是不帶符號位的右移,x>>>1就是x的內(nèi)容右移一位,開頭補(bǔ)0(x的內(nèi)容并不改變)
    posted @ 2007-08-01 10:12 比特鼠 閱讀(2804) | 評論 (0)編輯 收藏

    原文地址 http://www.programbbs.com/doc/2433.htm
    為什么會排隊等待?

    下面的這個簡單的 Java 程序完成四項不相關(guān)的任務(wù)。這樣的程序有單個控制線程,控制在這四個任務(wù)之間線性地移動。此外,因為所需的資源 — 打印機(jī)、磁盤、數(shù)據(jù)庫和顯示屏 -- 由于硬件和軟件的限制都有內(nèi)在的潛伏時間,所以每項任務(wù)都包含明顯的等待時間。因此,程序在訪問數(shù)據(jù)庫之前必須等待打印機(jī)完成打印文件的任務(wù),等等。如果您正在等待程序的完成,則這是對計算資源和您的時間的一種拙劣使用。改進(jìn)此程序的一種方法是使它成為多線程的。
     
    四項不相關(guān)的任務(wù)
     

    class myclass {
        static public void main(String args[]) {
            print_a_file();
            manipulate_another_file();
            access_database();
            draw_picture_on_screen();
        }
    }

    在本例中,每項任務(wù)在開始之前必須等待前一項任務(wù)完成,即使所涉及的任務(wù)毫不相關(guān)也是這樣。但是,在現(xiàn)實(shí)生活中,我們經(jīng)常使用多線程模型。我們在處理某些任務(wù)的同時也可以讓孩子、配偶和父母完成別的任務(wù)。例如,我在寫信的同時可能打發(fā)我的兒子去郵局買郵票。用軟件術(shù)語來說,這稱為多個控制(或執(zhí)行)線程。

    可以用兩種不同的方法來獲得多個控制線程:

    多個進(jìn)程
    在大多數(shù)操作系統(tǒng)中都可以創(chuàng)建多個進(jìn)程。當(dāng)一個程序啟動時,它可以為即將開始的每項任務(wù)創(chuàng)建一個進(jìn)程,并允許它們同時運(yùn)行。當(dāng)一個程序因等待網(wǎng)絡(luò)訪問或用戶輸入而被阻塞時,另一個程序還可以運(yùn)行,這樣就增加了資源利用率。但是,按照這種方式創(chuàng)建每個進(jìn)程要付出一定的代價:設(shè)置一個進(jìn)程要占用相當(dāng)一部分處理器時間和內(nèi)存資源。而且,大多數(shù)操作系統(tǒng)不允許進(jìn)程訪問其他進(jìn)程的內(nèi)存空間。因此,進(jìn)程間的通信很不方便,并且也不會將它自己提供給容易的編程模型。


    線程
    線程也稱為輕型進(jìn)程 (LWP)。因為線程只能在單個進(jìn)程的作用域內(nèi)活動,所以創(chuàng)建線程比創(chuàng)建進(jìn)程要廉價得多。這樣,因為線程允許協(xié)作和數(shù)據(jù)交換,并且在計算資源方面非常廉價,所以線程比進(jìn)程更可取。線程需要操作系統(tǒng)的支持,因此不是所有的機(jī)器都提供線程。Java 編程語言,作為相當(dāng)新的一種語言,已將線程支持與語言本身合為一體,這樣就對線程提供了強(qiáng)健的支持。


    使用 Java 編程語言實(shí)現(xiàn)線程
    Java 編程語言使多線程如此簡單有效,以致于某些程序員說它實(shí)際上是自然的。盡管在 Java 中使用線程比在其他語言中要容易得多,仍然有一些概念需要掌握。要記住的一件重要的事情是 main() 函數(shù)也是一個線程,并可用來做有用的工作。程序員只有在需要多個線程時才需要創(chuàng)建新的線程。

    Thread 類
    Thread 類是一個具體的類,即不是抽象類,該類封裝了線程的行為。要創(chuàng)建一個線程,程序員必須創(chuàng)建一個從 Thread 類導(dǎo)出的新類。程序員必須覆蓋 Thread 的 run() 函數(shù)來完成有用的工作。用戶并不直接調(diào)用此函數(shù);而是必須調(diào)用 Thread 的 start() 函數(shù),該函數(shù)再調(diào)用 run()。下面的代碼說明了它的用法:

    創(chuàng)建兩個新線程

    import java.util.*;

    class TimePrinter extends Thread {
        int pauseTime;

        String name;

        public TimePrinter(int x, String n) {
            pauseTime = x;
            name = n;
        }

        public void run() {
            while (true) {
                try {
                    System.out.println(name + ":"
                            + new Date(System.currentTimeMillis()));
                    Thread.sleep(pauseTime);
                } catch (Exception e) {
                    System.out.println(e);
                }
            }
        }

        static public void main(String args[]) {
            TimePrinter tp1 = new TimePrinter(1000, "Fast Guy");
            tp1.start();
            TimePrinter tp2 = new TimePrinter(3000, "Slow Guy");
            tp2.start();

        }
    }

    在本例中,我們可以看到一個簡單的程序,它按兩個不同的時間間隔(1 秒和 3 秒)在屏幕上顯示當(dāng)前時間。這是通過創(chuàng)建兩個新線程來完成的,包括 main() 共三個線程。但是,因為有時要作為線程運(yùn)行的類可能已經(jīng)是某個類層次的一部分,所以就不能再按這種機(jī)制創(chuàng)建線程。雖然在同一個類中可以實(shí)現(xiàn)任意數(shù)量的接口,但 Java 編程語言只允許一個類有一個父類。同時,某些程序員避免從 Thread 類導(dǎo)出,因為它強(qiáng)加了類層次。對于這種情況,就要 runnable 接口。

    Runnable 接口
    此接口只有一個函數(shù),run(),此函數(shù)必須由實(shí)現(xiàn)了此接口的類實(shí)現(xiàn)。但是,就運(yùn)行這個類而論,其語義與前一個示例稍有不同。我們可以用 runnable 接口改寫前一個示例。(不同的部分用黑體表示。)

    創(chuàng)建兩個新線程而不強(qiáng)加類層次

    import java.util.*;

    class TimePrinter implements Runnable {
        int pauseTime;

        String name;

        public TimePrinter(int x, String n) {
            pauseTime = x;
            name = n;
        }

        public void run() {
            while (true) {
                try {
                    System.out.println(name + ":"
                            + new Date(System.currentTimeMillis()));
                    Thread.sleep(pauseTime);
                } catch (Exception e) {
                    System.out.println(e);
                }
            }
        }

        static public void main(String args[]) {
            Thread t1 = new Thread(new TimePrinter(1000, "Fast Guy"));
            t1.start();
            Thread t2 = new Thread(new TimePrinter(3000, "Slow Guy"));
            t2.start();

        }
    }

    請注意,當(dāng)使用 runnable 接口時,您不能直接創(chuàng)建所需類的對象并運(yùn)行它;必須從 Thread 類的一個實(shí)例內(nèi)部運(yùn)行它。許多程序員更喜歡 runnable 接口,因為從 Thread 類繼承會強(qiáng)加類層次。

    synchronized 關(guān)鍵字
    到目前為止,我們看到的示例都只是以非常簡單的方式來利用線程。只有最小的數(shù)據(jù)流,而且不會出現(xiàn)兩個線程訪問同一個對象的情況。但是,在大多數(shù)有用的程序中,線程之間通常有信息流。試考慮一個金融應(yīng)用程序,它有一個 Account 對象,如下例中所示:

    一個銀行中的多項活動

    public class Account {
        String holderName;

        float amount;

        public Account(String name, float amt) {
            holderName = name;
            amount = amt;
        }

        public void deposit(float amt) {
            amount += amt;
        }

        public void withdraw(float amt) {
            amount -= amt;
        }

        public float checkBalance() {
            return amount;
        }
    }

    在此代碼樣例中潛伏著一個錯誤。如果此類用于單線程應(yīng)用程序,不會有任何問題。但是,在多線程應(yīng)用程序的情況中,不同的線程就有可能同時訪問同一個 Account 對象,比如說一個聯(lián)合帳戶的所有者在不同的 ATM 上同時進(jìn)行訪問。在這種情況下,存入和支出就可能以這樣的方式發(fā)生:一個事務(wù)被另一個事務(wù)覆蓋。這種情況將是災(zāi)難性的。但是,Java 編程語言提供了一種簡單的機(jī)制來防止發(fā)生這種覆蓋。每個對象在運(yùn)行時都有一個關(guān)聯(lián)的鎖。這個鎖可通過為方法添加關(guān)鍵字 synchronized 來獲得。這樣,修訂過的 Account 對象(如下所示)將不會遭受像數(shù)據(jù)損壞這樣的錯誤:

    對一個銀行中的多項活動進(jìn)行同步處理

    public class Account {
        String holderName;

        float amount;

        public Account(String name, float amt) {
            holderName = name;
            amount = amt;
        }

        public synchronized void deposit(float amt) {
            amount += amt;
        }

        public synchronized void withdraw(float amt) {
            amount -= amt;
        }

        public float checkBalance() {
            return amount;
        }
    }

    deposit() 和 withdraw() 函數(shù)都需要這個鎖來進(jìn)行操作,所以當(dāng)一個函數(shù)運(yùn)行時,另一個函數(shù)就被阻塞。請注意,checkBalance() 未作更改,它嚴(yán)格是一個讀函數(shù)。因為 checkBalance() 未作同步處理,所以任何其他方法都不會阻塞它,它也不會阻塞任何其他方法,不管那些方法是否進(jìn)行了同步處理。

    Java 編程語言中的高級多線程支持

    線程組
    線程是被個別創(chuàng)建的,但可以將它們歸類到線程組中,以便于調(diào)試和監(jiān)視。只能在創(chuàng)建線程的同時將它與一個線程組相關(guān)聯(lián)。在使用大量線程的程序中,使用線程組組織線程可能很有幫助??梢詫⑺鼈兛醋魇怯嬎銠C(jī)上的目錄和文件結(jié)構(gòu)。

    線程間發(fā)信
    當(dāng)線程在繼續(xù)執(zhí)行前需要等待一個條件時,僅有 synchronized 關(guān)鍵字是不夠的。雖然 synchronized 關(guān)鍵字阻止并發(fā)更新一個對象,但它沒有實(shí)現(xiàn)線程間發(fā)信。Object 類為此提供了三個函數(shù):wait()、notify() 和 notifyAll()。以全球氣候預(yù)測程序為例。這些程序通過將地球分為許多單元,在每個循環(huán)中,每個單元的計算都是隔離進(jìn)行的,直到這些值趨于穩(wěn)定,然后相鄰單元之間就會交換一些數(shù)據(jù)。所以,從本質(zhì)上講,在每個循環(huán)中各個線程都必須等待所有線程完成各自的任務(wù)以后才能進(jìn)入下一個循環(huán)。這個模型稱為屏蔽同步,下例說明了這個模型:

    屏蔽同步

    public class BSync {
        int totalThreads;

        int currentThreads;

        public BSync(int x) {
            totalThreads = x;
            currentThreads = 0;
        }

        public synchronized void waitForAll() {
            currentThreads++;
            if (currentThreads < totalThreads) {
                try {
                    wait();
                } catch (Exception e) {
                }
            } else {
                currentThreads = 0;
                notifyAll();
            }
        }
    }

    當(dāng)對一個線程調(diào)用 wait() 時,該線程就被有效阻塞,只到另一個線程對同一個對象調(diào)用 notify() 或 notifyAll() 為止。因此,在前一個示例中,不同的線程在完成它們的工作以后將調(diào)用 waitForAll() 函數(shù),最后一個線程將觸發(fā) notifyAll() 函數(shù),該函數(shù)將釋放所有的線程。第三個函數(shù) notify() 只通知一個正在等待的線程,當(dāng)對每次只能由一個線程使用的資源進(jìn)行訪問限制時,這個函數(shù)很有用。但是,不可能預(yù)知哪個線程會獲得這個通知,因為這取決于 Java 虛擬機(jī) (JVM) 調(diào)度算法。

    將 CPU 讓給另一個線程
    當(dāng)線程放棄某個稀有的資源(如數(shù)據(jù)庫連接或網(wǎng)絡(luò)端口)時,它可能調(diào)用 yield() 函數(shù)臨時降低自己的優(yōu)先級,以便某個其他線程能夠運(yùn)行。

    守護(hù)線程
    有兩類線程:用戶線程和守護(hù)線程。用戶線程是那些完成有用工作的線程。守護(hù)線程是那些僅提供輔助功能的線程。Thread 類提供了 setDaemon() 函數(shù)。Java 程序?qū)⑦\(yùn)行到所有用戶線程終止,然后它將破壞所有的守護(hù)線程。在 Java 虛擬機(jī) (JVM) 中,即使在 main 結(jié)束以后,如果另一個用戶線程仍在運(yùn)行,則程序仍然可以繼續(xù)運(yùn)行。

    避免不提倡使用的方法
    不提倡使用的方法是為支持向后兼容性而保留的那些方法,它們在以后的版本中可能出現(xiàn),也可能不出現(xiàn)。Java 多線程支持在版本 1.1 和版本 1.2 中做了重大修訂,stop()、suspend() 和 resume() 函數(shù)已不提倡使用。這些函數(shù)在 JVM 中可能引入微妙的錯誤。雖然函數(shù)名可能聽起來很誘人,但請抵制誘惑不要使用它們。

    調(diào)試線程化的程序
    在線程化的程序中,可能發(fā)生的某些常見而討厭的情況是死鎖、活鎖、內(nèi)存損壞和資源耗盡。

    死鎖
    死鎖可能是多線程程序最常見的問題。當(dāng)一個線程需要一個資源而另一個線程持有該資源的鎖時,就會發(fā)生死鎖。這種情況通常很難檢測。但是,解決方案卻相當(dāng)好:在所有的線程中按相同的次序獲取所有資源鎖。例如,如果有四個資源 —A、B、C 和 D — 并且一個線程可能要獲取四個資源中任何一個資源的鎖,則請確保在獲取對 B 的鎖之前首先獲取對 A 的鎖,依此類推。如果“線程 1”希望獲取對 B 和 C 的鎖,而“線程 2”獲取了 A、C 和 D 的鎖,則這一技術(shù)可能導(dǎo)致阻塞,但它永遠(yuǎn)不會在這四個鎖上造成死鎖。

    活鎖
    當(dāng)一個線程忙于接受新任務(wù)以致它永遠(yuǎn)沒有機(jī)會完成任何任務(wù)時,就會發(fā)生活鎖。這個線程最終將超出緩沖區(qū)并導(dǎo)致程序崩潰。試想一個秘書需要錄入一封信,但她一直在忙于接電話,所以這封信永遠(yuǎn)不會被錄入。

    內(nèi)存損壞
    如果明智地使用 synchronized 關(guān)鍵字,則完全可以避免內(nèi)存錯誤這種氣死人的問題。

    資源耗盡
    某些系統(tǒng)資源是有限的,如文件描述符。多線程程序可能耗盡資源,因為每個線程都可能希望有一個這樣的資源。如果線程數(shù)相當(dāng)大,或者某個資源的侯選線程數(shù)遠(yuǎn)遠(yuǎn)超過了可用的資源數(shù),則最好使用資源池。一個最好的示例是數(shù)據(jù)庫連接池。只要線程需要使用一個數(shù)據(jù)庫連接,它就從池中取出一個,使用以后再將它返回池中。資源池也稱為資源庫。

    調(diào)試大量的線程
    有時一個程序因為有大量的線程在運(yùn)行而極難調(diào)試。在這種情況下,下面的這個類可能會派上用場:

    public class Probe extends Thread {
        public Probe() {
        }

        public void run() {

            while (true) {
                Thread[] x = new Thread[100];
                Thread.enumerate(x);

                for (int i = 0; i < 100; i++) {
                    Thread t = x[i];
                    if (t == null)
                        break;
                    else
                        System.out.println(t.getName() + "\t" + t.getPriority()
                                + "\t" + t.isAlive() + "\t" + t.isDaemon());
                }
            }
        }
    }

    限制線程優(yōu)先級和調(diào)度
    Java 線程模型涉及可以動態(tài)更改的線程優(yōu)先級。本質(zhì)上,線程的優(yōu)先級是從 1 到 10 之間的一個數(shù)字,數(shù)字越大表明任務(wù)越緊急。JVM 標(biāo)準(zhǔn)首先調(diào)用優(yōu)先級較高的線程,然后才調(diào)用優(yōu)先級較低的線程。但是,該標(biāo)準(zhǔn)對具有相同優(yōu)先級的線程的處理是隨機(jī)的。如何處理這些線程取決于基層的操作系統(tǒng)策略。在某些情況下,優(yōu)先級相同的線程分時運(yùn)行;在另一些情況下,線程將一直運(yùn)行到結(jié)束。請記住,Java 支持 10 個優(yōu)先級,基層操作系統(tǒng)支持的優(yōu)先級可能要少得多,這樣會造成一些混亂。因此,只能將優(yōu)先級作為一種很粗略的工具使用。最后的控制可以通過明智地使用 yield() 函數(shù)來完成。通常情況下,請不要依靠線程優(yōu)先級來控制線程的狀態(tài)。

    小結(jié)
    本文說明了在 Java 程序中如何使用線程。像是否應(yīng)該使用線程這樣的更重要的問題在很大程序上取決于手頭的應(yīng)用程序。決定是否在應(yīng)用程序中使用多線程的一種方法是,估計可以并行運(yùn)行的代碼量。并記住以下幾點(diǎn):

    使用多線程不會增加 CPU 的能力。但是如果使用 JVM 的本地線程實(shí)現(xiàn),則不同的線程可以在不同的處理器上同時運(yùn)行(在多 CPU 的機(jī)器中),從而使多 CPU 機(jī)器得到充分利用。
    如果應(yīng)用程序是計算密集型的,并受 CPU 功能的制約,則只有多 CPU 機(jī)器能夠從更多的線程中受益。
    當(dāng)應(yīng)用程序必須等待緩慢的資源(如網(wǎng)絡(luò)連接或數(shù)據(jù)庫連接)時,或者當(dāng)應(yīng)用程序是非交互式的時,多線程通常是有利的。
    基于 Internet 的軟件有必要是多線程的;否則,用戶將感覺應(yīng)用程序反映遲鈍。例如,當(dāng)開發(fā)要支持大量客戶機(jī)的服務(wù)器時,多線程可以使編程較為容易。在這種情況下,每個線程可以為不同的客戶或客戶組服務(wù),從而縮短了響應(yīng)時間。

    某些程序員可能在 C 和其他語言中使用過線程,在那些語言中對線程沒有語言支持。這些程序員可能通常都被搞得對線程失去了信心。

    posted @ 2007-07-30 09:36 比特鼠 閱讀(209) | 評論 (0)編輯 收藏

    眾所周知, Java在從XML文件中裝載內(nèi)容到內(nèi)存過程中,不論用何種方式,IO操作的開銷都無可避免。本文嘗試比較dom4j中的XPP3和SAX兩種方式裝載XML文件的性能,以便將IO操作的開銷降到最小!

    package gz.lwm;

    import java.io.File;
    import org.apache.log4j.Logger;
    import org.dom4j.Document;
    import org.dom4j.DocumentHelper;
    import org.dom4j.io.SAXReader;
    import org.dom4j.io.XPP3Reader;

    public class TestDom4j {
     private static final Logger log = Logger.getLogger(TestDom4j.class);
     private static long bt; 
     
     public static void main(String[] args) {
      Document doc = DocumentHelper.createDocument();   
      //先運(yùn)行g(shù)etXmlSAX()
      bt = System.currentTimeMillis();
      String strXml = getXmlSAX("xml/test.xml");
      if(log.isDebugEnabled()){
       log.debug("\ngetXmlSAX() use time: " + (System.currentTimeMillis() - bt) + " millis\n");
      }

      //再運(yùn)行g(shù)etXmlXPP3()
      bt = System.currentTimeMillis();
      String s1 =getXmlXPP3("xml/test.xml");
      if(log.isDebugEnabled()){
       log.debug("\ngetXmlXPP3() use time: " + (System.currentTimeMillis() - bt) + " millis\n");
      }
      
      
     }
     
     public static String getXmlSAX(String xmlFile){
      String result = "";
      try {
       SAXReader reader = new SAXReader();
       Document document = reader.read(new File(xmlFile));
       result = document.asXML();
      } catch (Exception e) {
       e.printStackTrace();
      }
      return result;
     }
     
     public static String getXmlXPP3(String xmlFile){
      String result = "";
      try {
       XPP3Reader reader = new XPP3Reader();
       Document document = reader.read(new File(xmlFile));
       result = document.asXML();
      } catch (Exception e) {
       e.printStackTrace();
      }
      return result;
     }


     
    }

    有沒有這一句"Document doc = DocumentHelper.createDocument()",對性能的影響很大,特別是對大xml文件(盡管并沒有使用doc)

    另外, getXmlXSAX()和getXmlXPP3()運(yùn)行的先后次序?qū)π阅艿挠绊懸埠艽螅?br>
    測試:
        在我的機(jī)器上,對一個100k左右的XML文件進(jìn)行多次測試后的均值結(jié)果為:

        getXmlXPP3() use time: 265 millis
        ...
        getXmlXSAX() use time: 359 millis
        ...

    結(jié)論:
        通過比較,在讀取XML文件上,XPP3略為優(yōu)于SAX!


    注意:

    要運(yùn)行例子,classpath需包含:
    dom4j-1.6.1.jar
    jaxen-1.1-beta-10.jar
    log4j-1.2.9.jar
    pull-parser-2.1.10.jar
    xpp3-1.1.4c.jar


    參考:
    dom4j :  http://www.dom4j.org/
    XPP   :  http://www.extreme.indiana.edu/xgws/xsoap/xpp/

    posted @ 2007-05-19 00:39 比特鼠 閱讀(2509) | 評論 (0)編輯 收藏

       Namespace namespace ...

       //第一種方法
       Document doc = DocumentHelper.createDocument();
       Element root = doc.addElement("Root", namespace.getURI());
       Element eResultMessage = root.addElement("ResultMessage");

       結(jié)果為:
       <Root xmlns="http://aaaaaa"><ResultMessage>...</ResultMessage></Root>



       //第二種方法
       Document doc = DocumentHelper.createDocument();
       Element root = doc.addElement(("Root");
       root.add(namespace);
       Element eResultMessage = root.addElement("ResultMessage");
       
       結(jié)果為:
       <Root xmlns="
    http://aaaaaa"><ResultMessage xmlns="">...</ResultMessage></Root>

    posted @ 2007-05-17 21:08 比特鼠 閱讀(2659) | 評論 (0)編輯 收藏

    正則表達(dá)式語法 
     

    正則表達(dá)式是一種文本模式,包括普通字符(例如,a 到 z 之間的字母)和特殊字符(稱為“元字符”)。模式描述在搜索文本時要匹配的一個或多個字符串。

    正則表達(dá)式示例
     
    表達(dá)式  匹配 
    /^\s*$/
     匹配空行。
     
    /\d{2}-\d{5}/
     驗證由兩位數(shù)字、一個連字符再加 5 位數(shù)字組成的 ID 號。
     
    /<\s*(\S+)(\s[^>]*)?>[\s\S]*<\s*\/\1\s*>/
     匹配 HTML 標(biāo)記。
     

    下表包含了元字符的完整列表以及它們在正則表達(dá)式上下文中的行為:

     
    字符  說明 
    \
     將下一字符標(biāo)記為特殊字符、文本、反向引用或八進(jìn)制轉(zhuǎn)義符。例如,“n”匹配字符“n”。“\n”匹配換行符。序列“\\”匹配“\”,“\(”匹配“(”。
     
    ^
     匹配輸入字符串開始的位置。如果設(shè)置了 RegExp 對象的 Multiline 屬性,^ 還會與“\n”或“\r”之后的位置匹配。
     
    $
     匹配輸入字符串結(jié)尾的位置。如果設(shè)置了 RegExp 對象的 Multiline 屬性,$ 還會與“\n”或“\r”之前的位置匹配。
     
    *
     零次或多次匹配前面的字符或子表達(dá)式。例如,zo* 匹配“z”和“zoo”。* 等效于 {0,}。
     
    +
     一次或多次匹配前面的字符或子表達(dá)式。例如,“zo+”與“zo”和“zoo”匹配,但與“z”不匹配。+ 等效于 {1,}。
     
    ?
     零次或一次匹配前面的字符或子表達(dá)式。例如,“do(es)?”匹配“do”或“does”中的“do”。? 等效于 {0,1}。
     
    {n}
     n 是非負(fù)整數(shù)。正好匹配 n 次。例如,“o{2}”與“Bob”中的“o”不匹配,但與“food”中的兩個“o”匹配。
     
    {n,}
     n 是非負(fù)整數(shù)。至少匹配 n 次。例如,“o{2,}”不匹配“Bob”中的“o”,而匹配“foooood”中的所有 o。“o{1,}”等效于“o+”。“o{0,}”等效于“o*”。
     
    {n,m}
     M 和 n 是非負(fù)整數(shù),其中 n <= m。匹配至少 n 次,至多 m 次。例如,“o{1,3}”匹配“fooooood”中的頭三個 o。'o{0,1}' 等效于 'o?'。注意:您不能將空格插入逗號和數(shù)字之間。
     
    ?
     當(dāng)此字符緊隨任何其他限定符(*、+、?、{n}、{n,}、{n,m})之后時,匹配模式是“非貪心的”。“非貪心的”模式匹配搜索到的、盡可能短的字符串,而默認(rèn)的“貪心的”模式匹配搜索到的、盡可能長的字符串。例如,在字符串“oooo”中,“o+?”只匹配單個“o”,而“o+”匹配所有“o”。
     
    .
     匹配除“\n”之外的任何單個字符。若要匹配包括“\n”在內(nèi)的任意字符,請使用諸如“[\s\S]”之類的模式。
     
    (pattern)
     匹配 pattern 并捕獲該匹配的子表達(dá)式。可以使用 $0…$9 屬性從結(jié)果“匹配”集合中檢索捕獲的匹配。若要匹配括號字符 ( ),請使用“\(”或者“\)”。
     
    (?:pattern)
     匹配 pattern 但不捕獲該匹配的子表達(dá)式,即它是一個非捕獲匹配,不存儲供以后使用的匹配。這對于用“or”字符 (|) 組合模式部件的情況很有用。例如,'industr(?:y|ies) 是比 'industry|industries' 更經(jīng)濟(jì)的表達(dá)式。
     
    (?=pattern)
     執(zhí)行正向預(yù)測先行搜索的子表達(dá)式,該表達(dá)式匹配處于匹配 pattern 的字符串的起始點(diǎn)的字符串。它是一個非捕獲匹配,即不能捕獲供以后使用的匹配。例如,'Windows (?=95|98|NT|2000)' 匹配“Windows 2000”中的“Windows”,但不匹配“Windows 3.1”中的“Windows”。預(yù)測先行不占用字符,即發(fā)生匹配后,下一匹配的搜索緊隨上一匹配之后,而不是在組成預(yù)測先行的字符后。
     
    (?!pattern)
     執(zhí)行反向預(yù)測先行搜索的子表達(dá)式,該表達(dá)式匹配不處于匹配 pattern 的字符串的起始點(diǎn)的搜索字符串。它是一個非捕獲匹配,即不能捕獲供以后使用的匹配。例如,'Windows (?!95|98|NT|2000)' 匹配“Windows 3.1”中的 “Windows”,但不匹配“Windows 2000”中的“Windows”。預(yù)測先行不占用字符,即發(fā)生匹配后,下一匹配的搜索緊隨上一匹配之后,而不是在組成預(yù)測先行的字符后。
     
    x|y
     匹配 x 或 y。例如,'z|food' 匹配“z”或“food”。'(z|f)ood' 匹配“zood”或“food”。
     
    [xyz]
     字符集。匹配包含的任一字符。例如,“[abc]”匹配“plain”中的“a”。
     
    [^xyz]
     反向字符集。匹配未包含的任何字符。例如,“[^abc]”匹配“plain”中的“p”。
     
    [a-z]
     字符范圍。匹配指定范圍內(nèi)的任何字符。例如,“[a-z]”匹配“a”到“z”范圍內(nèi)的任何小寫字母。
     
    [^a-z]
     反向范圍字符。匹配不在指定的范圍內(nèi)的任何字符。例如,“[^a-z]”匹配任何不在“a”到“z”范圍內(nèi)的任何字符。
     
    \b
     匹配一個字邊界,即字與空格間的位置。例如,“er\b”匹配“never”中的“er”,但不匹配“verb”中的“er”。
     
    \B
     非字邊界匹配。“er\B”匹配“verb”中的“er”,但不匹配“never”中的“er”。
     
    \cx
     匹配 x 指示的控制字符。例如,\cM 匹配 Control-M 或回車符。x 的值必須在 A-Z 或 a-z 之間。如果不是這樣,則假定 c 就是“c”字符本身。
     
    \d
     數(shù)字字符匹配。等效于 [0-9]。
     
    \D
     非數(shù)字字符匹配。等效于 [^0-9]。
     
    \f
     換頁符匹配。等效于 \x0c 和 \cL。
     
    \n
     換行符匹配。等效于 \x0a 和 \cJ。
     
    \r
     匹配一個回車符。等效于 \x0d 和 \cM。
     
    \s
     匹配任何空白字符,包括空格、制表符、換頁符等。與 [ \f\n\r\t\v] 等效。
     
    \S
     匹配任何非空白字符。與 [^ \f\n\r\t\v] 等效。
     
    \t
     制表符匹配。與 \x09 和 \cI 等效。
     
    \v
     垂直制表符匹配。與 \x0b 和 \cK 等效。
     
    \w
     匹配任何字類字符,包括下劃線。與“[A-Za-z0-9_]”等效。
     
    \W
     與任何非單詞字符匹配。與“[^A-Za-z0-9_]”等效。
     
    \xn
     匹配 n,此處的 n 是一個十六進(jìn)制轉(zhuǎn)義碼。十六進(jìn)制轉(zhuǎn)義碼必須正好是兩位數(shù)長。例如,“\x41”匹配“A”。“\x041”與“\x04”&“1”等效。允許在正則表達(dá)式中使用 ASCII 代碼。
     
    \num
     匹配 num,此處的 num 是一個正整數(shù)。到捕獲匹配的反向引用。例如,“(.)\1”匹配兩個連續(xù)的相同字符。
     
    \n
     標(biāo)識一個八進(jìn)制轉(zhuǎn)義碼或反向引用。如果 \n 前面至少有 n 個捕獲子表達(dá)式,那么 n 是反向引用。否則,如果 n 是八進(jìn)制數(shù) (0-7),那么 n 是八進(jìn)制轉(zhuǎn)義碼。
     
    \nm
     標(biāo)識一個八進(jìn)制轉(zhuǎn)義碼或反向引用。如果 \nm 前面至少有 nm 個捕獲子表達(dá)式,那么 nm 是反向引用。如果 \nm 前面至少有 n 個捕獲,則 n 是反向引用,后面跟有字符 m。如果兩種前面的情況都不存在,則 \nm 匹配八進(jìn)制值 nm,其中 n 和 m 是八進(jìn)制數(shù)字 (0-7)。
     
    \nml
     當(dāng) n 是八進(jìn)制數(shù) (0-3),m 和 l 是八進(jìn)制數(shù) (0-7) 時,匹配八進(jìn)制轉(zhuǎn)義碼 nml。
     
    \un
     匹配 n,其中 n 是以四位十六進(jìn)制數(shù)表示的 Unicode 字符。例如,\u00A9 匹配版權(quán)符號 (?)。
     

    posted @ 2007-05-17 10:48 比特鼠 閱讀(7536) | 評論 (0)編輯 收藏

    package com.sunrise.ocs.webservice.unicom.test;

    import java.io.File;
    import java.io.StringWriter;
    import java.util.HashMap;
    import java.util.Iterator;

    import javax.xml.parsers.DocumentBuilderFactory;

    import org.apache.log4j.Logger;
    import org.dom4j.Document;
    import org.dom4j.DocumentHelper;
    import org.dom4j.Element;
    import org.dom4j.XPath;
    import org.dom4j.io.SAXReader;

    import com.sun.org.apache.xml.internal.serialize.OutputFormat;
    import com.sun.org.apache.xml.internal.serialize.XMLSerializer;

    public class TestDom4j {
     private static final Logger log = Logger.getLogger(TestDom4j.class);

     private static long bt;

     public static void main(String[] args) {
      String strXml = "";
      int b = 0;
      String file1 = "xml/CreateUserRequest.xml";
      String file2 = "xml/CancelUserRequest.xml";
      if(b==0){
       bt = System.currentTimeMillis();
       strXml = xmlFile2String(file1);
       if (log.isDebugEnabled()) {
        log.debug("\nxmlFile2String() use time: "
          + (System.currentTimeMillis() - bt) + " millis\n");
       }
      }else{
       bt = System.currentTimeMillis();
       strXml = xmlFile2String2(file1);
       if (log.isDebugEnabled()) {
        log.debug("\nxmlFile2String2() use time: "
          + (System.currentTimeMillis() - bt) + " millis\n");
       }
      }

      if(b==0){
       bt = System.currentTimeMillis();
       findElement4XPath1(strXml);
       if (log.isDebugEnabled()) {
        log.debug("\nfindElement4XPath1() use time: "
          + (System.currentTimeMillis() - bt) + " millis\n");
       }
      }else{
       bt = System.currentTimeMillis();
       findElement4XPath2(strXml);
       if (log.isDebugEnabled()) {
        log.debug("\nfindElement4XPath2() use time: "
          + (System.currentTimeMillis() - bt) + " millis\n");
       } 
       
      }
     }

     public static void findElement4XPath1(String xml) {
      try {
       String str = delNamespace4Pattern(xml);
       Document doc = DocumentHelper.parseText(str);
       Element e = (Element) doc.selectSingleNode("http://CreateUserRequest/RequestMessage/MessageHeader");
       if (e != null) {
        Iterator iter = e.elementIterator();
        while (iter.hasNext()) {
         Element sub = (Element) iter.next();
         log.debug("\n" + sub.getText() + "\n");
        }
       }
       
       /* 讀取屬性的例子
       List childNodes = doc.selectNodes("http://Config/Child/ChildNode");
             for(Object obj:childNodes) {
                 Node childNode = (Node)obj;
                 String name = childNode.valueOf("@name"); //讀取屬性
                 String text = childNode.getText();
             }
             */

       
      } catch (Exception e) {
       e.printStackTrace();
      }
     }
     public static void findElement4XPath2(String xml) {
      try {
       Document doc = DocumentHelper.parseText(xml);
       Element root = doc.getRootElement();
       
       HashMap map = new HashMap();
       map.put("tns", "   XPath x = doc.createXPath("http://tns:CreateUserRequest/tns:RequestMessage/tns:MessageHeader");
       x.setNamespaceURIs(map);
       
       Element e = (Element) x.selectSingleNode(doc);
       if (e != null) {
        Iterator iter = e.elementIterator();
        while (iter.hasNext()) {
         Element sub = (Element) iter.next();
         if (log.isDebugEnabled()) {
          log.debug("\n" + sub.getText() + "\n");
         }
        }
       }
      } catch (Exception e) {
       e.printStackTrace();
      }
     }

     public static Document xml2Document(String xml) {
      try {
       return DocumentHelper.parseText(xml);
      } catch (Exception e) {
       e.printStackTrace();
      }
      return null;
     }

     public static String xmlFile2String(String xmlFile) {
      try {
       return new SAXReader().read(new File(xmlFile)).asXML();
      } catch (Exception e) {
       e.printStackTrace();
      }
      return null;
     }
     
     //讀取xml文件為xml串
     public static String xmlFile2String2(String xmlFile) {
      try {
       org.w3c.dom.Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(xmlFile); 
       OutputFormat format = new OutputFormat(document);
       //format.setEncoding("UTF-8");
       StringWriter stringOut = new StringWriter();
       XMLSerializer serial = new XMLSerializer(stringOut, format);
       serial.asDOMSerializer();
       serial.serialize(document.getDocumentElement());
       return stringOut.toString();
      } catch (Exception e) {
       e.printStackTrace();
      }
      return "";
     }
     
     
     public static String delNamespace4Pattern(String xml){
      String result = "";
      try {
       result = xml.replaceFirst("xmlns([^ ]*)=([^ ]*)http([^>^\"]*)\"", "");
      } catch (Exception e) {
       e.printStackTrace();
      }
      return result;
      
     }

     

    }

    posted @ 2007-05-17 10:46 比特鼠 閱讀(208) | 評論 (0)編輯 收藏

    package com.sunrise.ocs.webservice.unicom.test;

    import java.io.File;
    import java.io.StringReader;
    import java.io.StringWriter;

    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;

    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    import org.w3c.dom.Node;
    import org.xml.sax.InputSource;

    import com.sun.org.apache.xml.internal.serialize.OutputFormat;
    import com.sun.org.apache.xml.internal.serialize.XMLSerializer;

    public class TestDom {
     
     //將xml串轉(zhuǎn)換為document
     public static Document xml2Document(String xml) {
      Document doc = null;
      try {
       DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
       doc = builder.parse(new InputSource(new StringReader(xml)));
      } catch (Exception e) {
       e.printStackTrace();
      }
      return doc;
     }
     
     //將xml文件串轉(zhuǎn)換為document
     public static Document xmlFile2Document(String xmlFile) {
      Document doc = null;
      try {
       DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
       doc = builder.parse(new File(xmlFile));
      } catch (Exception e) {
       e.printStackTrace();
      }
      return doc;
     }
     
     //刪除命名空間: xmlns="..."
     public static String delNamespace(String xml) {
      String result = xml;
      try {
       Document doc = xml2Document(xml);
       Element root = doc.getDocumentElement();
       root.removeAttribute("xmlns");
       result = asXml(doc);
      } catch (Exception e) {
       e.printStackTrace();
      }
      return result;
     }
     
     //將doc轉(zhuǎn)換為xml串
     public static String asXml(Document doc) {
      String strxml = "";
      try {
       OutputFormat format = new OutputFormat(doc);
       // format.setEncoding("UTF-8");
       StringWriter stringOut = new StringWriter();
       XMLSerializer serial = new XMLSerializer(stringOut, format);
       serial.asDOMSerializer();
       serial.serialize(doc.getDocumentElement());
       strxml = stringOut.toString();
      } catch (Exception e) {
       e.printStackTrace();
      }
      return strxml;
     }
     
     //將node轉(zhuǎn)換為xml串
     public static String asXml(Node node, Document doc) {
      String strxml = "";
      try {
       OutputFormat format = new OutputFormat(doc);
       // format.setEncoding("UTF-8");
       StringWriter stringOut = new StringWriter();
       XMLSerializer serial = new XMLSerializer(stringOut, format);
       serial.asDOMSerializer();
       serial.serialize((Element)node);
       strxml = stringOut.toString();
      } catch (Exception e) {
       e.printStackTrace();
      }
      return strxml;
     }
    }

    posted @ 2007-05-17 10:10 比特鼠 閱讀(283) | 評論 (0)編輯 收藏

    主站蜘蛛池模板: 亚洲一卡2卡三卡4卡无卡下载| 亚洲国产天堂久久久久久| 黄色一级视频免费| 免费看片在线观看| 国产亚洲成人久久| 亚洲AⅤ男人的天堂在线观看| 青青草a免费线观a| 亚洲成aⅴ人在线观看| 永久黄色免费网站| 亚洲精品**中文毛片| 国产精品免费观看| 亚洲国产成人久久| 91免费资源网站入口| 亚洲一区二区三区高清在线观看| 免费国产黄线在线观看| 亚洲精品乱码久久久久久V | 色偷偷亚洲第一综合| 成人黄动漫画免费网站视频 | 2020久久精品亚洲热综合一本| 国产免费不卡v片在线观看| 色噜噜亚洲男人的天堂| 国产精品色午夜免费视频| 成人一级免费视频| 亚洲国产高清在线| 在线精品免费视频| 免费精品国自产拍在线播放| 亚洲午夜激情视频| 精品视频一区二区三区免费| 亚洲精品亚洲人成在线麻豆| 国产精品美女午夜爽爽爽免费| 亚洲国产精品狼友中文久久久| 免费一区二区三区| 666精品国产精品亚洲| 69成人免费视频| 亚洲午夜无码久久久久软件| 国产裸模视频免费区无码| 亚洲乱码日产精品一二三| 永久看日本大片免费35分钟| 亚洲国产福利精品一区二区| 午夜两性色视频免费网站| 免费看黄福利app导航看一下黄色录像 |