• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            教父的告白
            一切都是紙老虎
            posts - 82,  comments - 7,  trackbacks - 0
            Code Profiler :

            在AX3+SP3中有一個(gè)工具Code Profiler,近來發(fā)現(xiàn)是非常好用的工具,可以檢查代碼運(yùn)行的軌跡,以及代碼運(yùn)行的時(shí)間,對(duì)于跟蹤代碼是非常有效的。


            C++代碼度量工具-cccc
            軟件度量多個(gè)指標(biāo)依賴于代碼行統(tǒng)計(jì),如每千行代碼發(fā)現(xiàn)bug等,所以代碼行是一個(gè)基礎(chǔ)數(shù)據(jù)。CCCC度量數(shù)據(jù)可結(jié)合測(cè)試風(fēng)險(xiǎn)完善測(cè)試計(jì)劃。


            CodeStatistics
            一個(gè)小的命令行工具。我主要用它來做兩件事情,一者是代碼統(tǒng)計(jì)功能;另一者是刪除空白行功能。在某此時(shí)候,我覺得對(duì)于整理代碼和了解代碼情況還是有一定的幫助作用的。明天我會(huì)將代碼的行結(jié)束符格式加上的,當(dāng)然,還有分析代碼元素,如有多少個(gè)函數(shù),多少個(gè)類,也在我確定要添加的功能之內(nèi)。當(dāng)然,能整理代碼就更棒了。


            靜態(tài)代碼分析工具Cppcheck
            Cppcheck是一款開源c++靜態(tài)代碼分析工具,在檢測(cè)源碼時(shí)可根據(jù)規(guī)則就能挖掘出疑似缺陷, 幫開源項(xiàng)目發(fā)現(xiàn)的bug:

            http://sourceforge.net/apps/mediawiki/cppcheck/index.php?title=Found_bugs

            功能比較強(qiáng)大,使用很簡(jiǎn)單



             

            posted @ 2010-09-13 16:45 暗夜教父 閱讀(575) | 評(píng)論 (0)編輯 收藏
                 摘要: 1.什么是canvas:引用Firefox開發(fā)者中心的一段話:<canvas> is a new HTML element which can be used to draw graphics using scripting (usuallyJavaScript). It can for instance be used to draw graphs, m...  閱讀全文
            posted @ 2010-05-20 09:41 暗夜教父 閱讀(2195) | 評(píng)論 (0)編輯 收藏
            在計(jì)算機(jī)領(lǐng)域,堆棧是一個(gè)不容忽視的概念,但是很多人甚至是計(jì)算機(jī)專業(yè)的人也沒有明確堆棧其實(shí)是兩種數(shù)據(jù)結(jié)構(gòu)。 
            堆棧都是一種數(shù)據(jù)項(xiàng)按序排列的數(shù)據(jù)結(jié)構(gòu),只能在一端(稱為棧頂(top))對(duì)數(shù)據(jù)項(xiàng)進(jìn)行插入和刪除。 
            要點(diǎn): 
            堆:順序隨意 
            棧:后進(jìn)先出(Last-In/First-Out) 
            編輯本段堆和棧的區(qū)別 
            一、預(yù)備知識(shí)—程序的內(nèi)存分配 
            一個(gè)由c/C++編譯的程序占用的內(nèi)存分為以下幾個(gè)部分 
            1、棧區(qū)(stack)— 由編譯器自動(dòng)分配釋放 ,存放函數(shù)的參數(shù)值,局部變量的值等。其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧。 
            2、堆區(qū)(heap) — 一般由程序員分配釋放, 若程序員不釋放,程序結(jié)束時(shí)可能由OS回收 。注意它與數(shù)據(jù)結(jié)構(gòu)中的堆是兩回事,分配方式倒是類似于鏈表。 
            3、全局區(qū)(靜態(tài)區(qū))(static)—,全局變量和靜態(tài)變量的存儲(chǔ)是放在一塊的,初始化的全局變量和靜態(tài)變量在一塊區(qū)域, 未初始化的全局變量和未初始化的靜態(tài)變量在相鄰的另一塊區(qū)域。 - 程序結(jié)束后由系統(tǒng)釋放。 
            4、文字常量區(qū) —常量字符串就是放在這里的。 程序結(jié)束后由系統(tǒng)釋放 。 
            5、程序代碼區(qū)—存放函數(shù)體的二進(jìn)制代碼。 
            二、例子程序 
            這是一個(gè)前輩寫的,非常詳細(xì) 
            //main.cpp 
            int a = 0; 全局初始化區(qū) 
            char *p1; 全局未初始化區(qū) 
            main() 

            int b; 棧 
            char s[] = "abc"; 棧 
            char *p2; 棧 
            char *p3 = "123456"; 123456\0在常量區(qū),p3在棧上。 
            static int c =0; 全局(靜態(tài))初始化區(qū) 
            p1 = (char *)malloc(10); 
            p2 = (char *)malloc(20); 

            分配得來得10和20字節(jié)的區(qū)域就在堆區(qū)。 
            strcpy(p1, "123456"); 123456\0放在常量區(qū),編譯器可能會(huì)將它與p3所指向的"123456"優(yōu)化成一個(gè)地方。 
            編輯本段堆和棧的理論知識(shí) 
            1.申請(qǐng)方式
            stack: 
            由系統(tǒng)自動(dòng)分配。 例如,聲明在函數(shù)中一個(gè)局部變量 int b; 系統(tǒng)自動(dòng)在棧中為b開辟空間 
            heap: 
            需要程序員自己申請(qǐng),并指明大小,在c中malloc函數(shù) 
            如p1 = (char *)malloc(10); 
            在C++中用new運(yùn)算符 
            如p2 = new char[20];//(char *)malloc(10); 
            但是注意p1、p2本身是在棧中的。 
            2.申請(qǐng)后系統(tǒng)的響應(yīng) 
            棧:只要棧的剩余空間大于所申請(qǐng)空間,系統(tǒng)將為程序提供內(nèi)存,否則將報(bào)異常提示棧溢出。 
            堆:首先應(yīng)該知道操作系統(tǒng)有一個(gè)記錄空閑內(nèi)存地址的鏈表,當(dāng)系統(tǒng)收到程序的申請(qǐng)時(shí),會(huì)遍歷該鏈表,尋找第一個(gè)空間大于所申請(qǐng)空間的堆結(jié)點(diǎn),然后將該結(jié)點(diǎn)從空閑結(jié)點(diǎn)鏈表中刪除,并將該結(jié)點(diǎn)的空間分配給程序,另外,對(duì)于大多數(shù)系統(tǒng),會(huì)在這塊內(nèi)存空間中的首地址處記錄本次分配的大小,這樣,代碼中的delete語句才能正確的釋放本內(nèi)存空間。另外,由于找到的堆結(jié)點(diǎn)的大小不一定正好等于申請(qǐng)的大小,系統(tǒng)會(huì)自動(dòng)的將多余的那部分重新放入空閑鏈表中。 
            3.申請(qǐng)大小的限制 
            棧:在Windows下,棧是向低地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu),是一塊連續(xù)的內(nèi)存的區(qū)域。這句話的意思是棧頂?shù)牡刂泛蜅5淖畲笕萘渴窍到y(tǒng)預(yù)先規(guī)定好的,在 WINDOWS下,棧的大小是2M(也有的說是1M,總之是一個(gè)編譯時(shí)就確定的常數(shù)),如果申請(qǐng)的空間超過棧的剩余空間時(shí),將提示overflow。因此,能從棧獲得的空間較小。 
            堆:堆是向高地址擴(kuò)展的數(shù)據(jù)結(jié)構(gòu),是不連續(xù)的內(nèi)存區(qū)域。這是由于系統(tǒng)是用鏈表來存儲(chǔ)的空閑內(nèi)存地址的,自然是不連續(xù)的,而鏈表的遍歷方向是由低地址向高地址。堆的大小受限于計(jì)算機(jī)系統(tǒng)中有效的虛擬內(nèi)存。由此可見,堆獲得的空間比較靈活,也比較大。 
            4.申請(qǐng)效率的比較 
            棧由系統(tǒng)自動(dòng)分配,速度較快。但程序員是無法控制的。 
            堆是由new分配的內(nèi)存,一般速度比較慢,而且容易產(chǎn)生內(nèi)存碎片,不過用起來最方便. 
            另外,在WINDOWS下,最好的方式是用VirtualAlloc分配內(nèi)存,他不是在堆,也不是在棧,而是直接在進(jìn)程的地址空間中保留一快內(nèi)存,雖然用起來最不方便。但是速度快,也最靈活 
            5.堆和棧中的存儲(chǔ)內(nèi)容 
            棧: 在函數(shù)調(diào)用時(shí),第一個(gè)進(jìn)棧的是主函數(shù)中函數(shù)調(diào)用后的下一條指令(函數(shù)調(diào)用語句的下一條可執(zhí)行語句)的地址,然后是函數(shù)的各個(gè)參數(shù),在大多數(shù)的C編譯器中,參數(shù)是由右往左入棧的,然后是函數(shù)中的局部變量。注意靜態(tài)變量是不入棧的。 
            當(dāng)本次函數(shù)調(diào)用結(jié)束后,局部變量先出棧,然后是參數(shù),最后棧頂指針指向最開始存的地址,也就是主函數(shù)中的下一條指令,程序由該點(diǎn)繼續(xù)運(yùn)行。 
            堆:一般是在堆的頭部用一個(gè)字節(jié)存放堆的大小。堆中的具體內(nèi)容有程序員安排。 
            6.存取效率的比較
            char s1[] = "aaaaaaaaaaaaaaa"; 
            char *s2 = "bbbbbbbbbbbbbbbbb"; 
            aaaaaaaaaaa是在運(yùn)行時(shí)刻賦值的; 
            而bbbbbbbbbbb是在編譯時(shí)就確定的; 
            但是,在以后的存取中,在棧上的數(shù)組比指針?biāo)赶虻淖址?例如堆)快。 
            比如: 
            #include 
            void main() 

            char a = 1; 
            char c[] = "1234567890"; 
            char *p ="1234567890"; 
            a = c[1]; 
            a = p[1]; 
            return; 

            對(duì)應(yīng)的匯編代碼 
            10: a = c[1]; 
            00401067 8A 4D F1 mov cl,byte ptr [ebp-0Fh] 
            0040106A 88 4D FC mov byte ptr [ebp-4],cl 
            11: a = p[1]; 
            0040106D 8B 55 EC mov edx,dword ptr [ebp-14h] 
            00401070 8A 42 01 mov al,byte ptr [edx+1] 
            00401073 88 45 FC mov byte ptr [ebp-4],al 
            第一種在讀取時(shí)直接就把字符串中的元素讀到寄存器cl中,而第二種則要先把指針值讀到edx中,在根據(jù)edx讀取字符,顯然慢了。 
            7.小結(jié): 
            堆和棧的區(qū)別可以用如下的比喻來看出: 
            使用棧就象我們?nèi)ワ堭^里吃飯,只管點(diǎn)菜(發(fā)出申請(qǐng))、付錢、和吃(使用),吃飽了就走,不必理會(huì)切菜、洗菜等準(zhǔn)備工作和洗碗、刷鍋等掃尾工作,他的好處是快捷,但是自由度小。 
            使用堆就象是自己動(dòng)手做喜歡吃的菜肴,比較麻煩,但是比較符合自己的口味,而且自由度大。 
            編輯本段堆和棧的區(qū)別主要分: 
            操作系統(tǒng)方面的堆和棧,如上面說的那些,不多說了。 
            還有就是數(shù)據(jù)結(jié)構(gòu)方面的堆和棧,這些都是不同的概念。這里的堆實(shí)際上指的就是(滿足堆性質(zhì)的)優(yōu)先隊(duì)列的一種數(shù)據(jù)結(jié)構(gòu),第1個(gè)元素有最高的優(yōu)先權(quán);棧實(shí)際上就是滿足先進(jìn)后出的性質(zhì)的數(shù)學(xué)或數(shù)據(jù)結(jié)構(gòu)。 
            雖然堆棧,堆棧的說法是連起來叫,但是他們還是有很大區(qū)別的,連著叫只是由于歷史的原因。
             
            ×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
            接下來主要講 symbian 中的應(yīng)用
             不管是在堆棧還是堆,對(duì)象都有自己的生命期,具體如下: 
              1、給對(duì)象分配內(nèi)存[堆棧或者堆] 
              2、初始化:也就是給對(duì)象所在的內(nèi)存賦值 
              3、使用對(duì)象 
                4、清除:釋放對(duì)象使用的各種資源 
              5、釋放對(duì)象所占的內(nèi)存[從堆棧或者堆] 
              對(duì)象的生存期是一個(gè)基礎(chǔ)概念。在某些操作系統(tǒng),它是可以忽略的,因?yàn)槌绦蛑兄沟臅r(shí)候,堆棧和堆都會(huì)被銷毀。但是在Symbian平臺(tái),程序往往需要能運(yùn)行數(shù)個(gè)月。這就是為什么對(duì)象在生命期結(jié)束的時(shí)候就必須馬上清除所有內(nèi)存是那么重要的原因,不管它們分配在堆棧還是堆,不管它們生命期的結(jié)束是因?yàn)檎L幚磉€是因?yàn)殄e(cuò)誤。 
            Lifetimes in C 略 
            Lifetimes in C++ 略 
            Lifetimes in the Symbian platform
            posted @ 2010-05-17 14:53 暗夜教父 閱讀(556) | 評(píng)論 (0)編輯 收藏
                 摘要: 轉(zhuǎn)自http://blog.csdn.net/summerfang/archive/2006/05/20/746219.aspx很長(zhǎng)時(shí)間里,我對(duì)“你什么時(shí)候會(huì)為PHPUnit寫一個(gè)文檔”這個(gè)問題的回答是:“你不需要PHPUnit文檔,去讀讀JUnit文檔或買一本Junit的書,試一試用PHP和PHPUnit來重寫Java和Junit的例子”。當(dāng)我和O...  閱讀全文
            posted @ 2010-04-13 19:30 暗夜教父 閱讀(482) | 評(píng)論 (0)編輯 收藏

            轉(zhuǎn)自http://blog.csdn.net/summerfang/archive/2006/05/20/746216.aspx

            聰明的Web開發(fā)人員會(huì)告訴你,越快找到代碼的錯(cuò)誤,你就能越快修正它,長(zhǎng)期而言,項(xiàng)目成本越低。好了,能最有效的檢測(cè)PHP代碼中的錯(cuò)誤的工具是PHPUnit,一個(gè)開發(fā)源代碼的框架,它在你不在的時(shí)候,自動(dòng)進(jìn)行成套的單元測(cè)試。使用PHPUnit的好處是顯而易見的:

            l         減少用于測(cè)試代碼的工作量

            l         減少總體軟件缺陷

            l         增加對(duì)代碼的信心

            l         改善你和開發(fā)源代碼的團(tuán)隊(duì)伙伴的關(guān)系

            直到現(xiàn)在,這個(gè)流行工具唯一的問題是缺乏文檔。為了解決這個(gè)問題,O’Reilly直接找到了源頭,PHPUnit口袋書指南的作者,也是PHPUnit的創(chuàng)造者,Sebastian Bergmann,來解決這個(gè)問題。這本書把很多難以記憶的信息,語法,PHPUnit工作的原則,統(tǒng)一到一起。它也帶來了只有技術(shù)創(chuàng)造者才能提供的洞察力和睿智忠告。而且,本書也談到了敏捷方法和極限編程中關(guān)于測(cè)試的內(nèi)容。

            O’Reilly口袋書指南最近的系列中,這本快速參考書把所有的答案都帶到了你的指尖。那些對(duì)測(cè)試PHP代碼感興趣的Web應(yīng)用程序開發(fā)者,會(huì)覺得本書是一個(gè)無價(jià)的伴侶。

             

            --------------------------------------------------------------------------------------------------------------

            原文:

            Overview

            Smart web developers will tell you that the sooner you detect your code mistakes, the quicker you can fix them, and the less the project will cost in the long run. Well, the most efficient way to detect your mistakes in PHP is with PHPUnit, an open source framework that automates unit testing by running a battery of tests as you go. The benefits of PHPUnit are significant:

             

            a reduction in the effort required to frequently test code

            fewer overall defects

            added confidence in your code

            improved relations with your open source teammates

             

             

             

            The only problem with this popular testing tool was its lack of documentation-until now, that is. For this, O'Reilly went right to the source, as Sebastian Bergmann, the author of PHPUnit Pocket Guide, also happens to be PHPUnit's creator. This little book brings together hard-to-remember information, syntax, and rules for working with PHPUnit. It also delivers the insight and sage advice that can only come from the technology's creator. Coverage of testing under agile methodologies and Extreme Programming (XP) is also included.

             

            The latest in O'Reilly's series of handy Pocket Guides, this quick-reference book puts all the answers are right at your fingertips. It's an invaluable companion for anyone interested in testing the PHP code they write for web applications.

            posted @ 2010-04-13 19:27 暗夜教父 閱讀(322) | 評(píng)論 (0)編輯 收藏
                 摘要: Flex ant tasks 提供了一種方便的手段使用工業(yè)標(biāo)準(zhǔn)級(jí)的構(gòu)建工具來編譯你的Flex工程。(The Flex Ant tasks provide a convenient way to build your Flex projects using an industry-standard build management...  閱讀全文
            posted @ 2010-04-12 15:08 暗夜教父 閱讀(1714) | 評(píng)論 (0)編輯 收藏
            對(duì)VS.NET工程進(jìn)行自動(dòng)構(gòu)建工作使用什么?也許大家會(huì)異口同聲的說是NANT。嗯,NANT無疑是自動(dòng)構(gòu)建VS.NET工程最快捷的工具,但對(duì)于一個(gè)擁有多個(gè)編程語言環(huán)境的項(xiàng)目,使用專用版的ANT工具卻并不是一個(gè)好的解決方案,試想,如果你的項(xiàng)目擁有多個(gè)由不同語言開發(fā)的模塊,那么你可能會(huì)同時(shí)使用ANT、WANT、NANT來分別管理特定的模塊。
            當(dāng)然,這不是我們想看到的,同時(shí)維護(hù)三個(gè)構(gòu)建工具實(shí)在不是什么明智之舉(當(dāng)然,如果你喜歡,那就無可厚非了),其實(shí)ANT已經(jīng)為我們通吃所有語言環(huán)境準(zhǔn)備好了精兵良駒。
            ANT的exec標(biāo)簽是用來執(zhí)行一個(gè)系統(tǒng)命令,這樣我們就可以使用開發(fā)工具的命令行編譯方法來完成相應(yīng)項(xiàng)目的自動(dòng)構(gòu)建工作。下面我們只介紹VS.NET工程的命令行編譯方法:
            VS.NET開發(fā)工具的命令行編譯命令是devenv,當(dāng)然前提是將VS.NET的IDE目錄路徑放置到PATH變量中。設(shè)置好PATH變量,在控制臺(tái)中鍵入devenv /?,我們可以看到VS.NET的各個(gè)參數(shù)說明,如下:

            Microsoft (R) 開發(fā)環(huán)境 7.10.3077 版。
            版權(quán)所有(C) Microsoft Corp 1984-2001。保留所有權(quán)利。
             
            用法:
            devenv [solutionfile | projectfile | anyfile.ext] [switches]
             
            可以調(diào)用 devenv,用第一個(gè)參數(shù)指定解決方案文件或項(xiàng)目文件。
            也可以調(diào)用 devenv,使第一個(gè)參數(shù)作為要在編輯器中打開的任何
            其他類型的文件。如果提供項(xiàng)目文件,IDE 將通過在與項(xiàng)目文件
            相同的目錄中查找與項(xiàng)目文件具有相同基名稱的 .sln 文件,在
            解決方案的上下文中打開該項(xiàng)目文件。如果存在 .sln 文件,則
            IDE 將查找引用該項(xiàng)目的單個(gè) .sln 文件。如果不存在這樣的單
            個(gè) .sln 文件,則 IDE 將創(chuàng)建一個(gè)具有默認(rèn) .sln 文件名的未保
            存的解決方案,而該默認(rèn)文件名與項(xiàng)目文件具有相同的基名稱。
             
            命令行生成:
            devenv solutionfile.sln /build solutionconfig [ /project projectnameorfile [ /p
            rojectconfig name ] ]
             
            可用的命令行開關(guān):
             
            /build          生成指定的解決方案配置
            /project        指定生成項(xiàng)目而不是解決方案
                            必須指定 /build 才能使用 /project
            /projectconfig 指定要生成的項(xiàng)目配置
                            必須指定 /project 才能使用 /projectconfig
            /out            將生成結(jié)果寫入指定的文件
            /rebuild         /build 類似,但先執(zhí)行強(qiáng)制清理
            /clean          清理生成結(jié)果
            /deploy         生成指定的解決方案配置然后部署它
            /run            運(yùn)行指定的解決方案配置
            /runexit        運(yùn)行指定的解決方案配置然后終止
            /command        啟動(dòng)后執(zhí)行指定的內(nèi)部命令行
            /mditabs        使用選項(xiàng)卡式文檔界面
            /mdi            使用 MDI 界面
            /fn             使用指定的字體名稱
            /fs             使用指定的字體大小
            /LCID           使用指定的語言 ID
            /noVSIP         禁用用于 VSIP 測(cè)試的VSIP 開發(fā)人員許可證密鑰
            /safemode       出于穩(wěn)定性僅加載默認(rèn)的環(huán)境和服務(wù)
            /resetskippkgs 允許曾被標(biāo)記為加載失敗的 VsPackages
                            再次加載
            /migratesettings 遷移另一個(gè)版本中的某些用戶設(shè)置
             
            產(chǎn)品特定的開關(guān):
             
            /debugexe       打開要調(diào)試的指定可執(zhí)行文件。
                            命令行的其余部分作為它的參數(shù)
                            傳遞到此執(zhí)行文件。
            /useenv         使用 PATHINCLUDELIBPATH  LIB 環(huán)境變量
                            而不是使用 VC++ 生成的 IDE 路徑。
             
            若要從命令行附加調(diào)試器,請(qǐng)使用:
                    vs7jit.exe -p <pid>

            可見VS.NET工具為我們提供了諸多支持命令行編譯的參數(shù),那接下來我們就開始動(dòng)手配置Build.xml文件吧,為了節(jié)省篇幅,我這里只給出compile任務(wù)的代碼:

            1    <target name="compile" depends="init">
            2        <mkdir dir="${pdcu}"/>
            3        <echo message="Compiling application main source..."/>
            4                 <delete file="${infofile}"/>        
            5        <exec dir="${pdir}\" executable="devenv" os="${build.os}" >
            6             <arg line=" ${pname}.sln
            7                                   /rebuild
            8                                   release     
            9                                   /useenv
            10                                 /out ${infofile}
            11                                 "/>
            12       </exec>
            13     <echo message="Compiling application main source complete."/>
            14 <loadfile property="compiled-info"
            15            srcFile="${infofile}"/>
            16        <echo message="${compiled-info}"/>       
            17 <condition property="compile-success">
            18      <and>
            19       <contains string="${compiled-info}" substring="0 已失敗"/>
            20      </and>
            21    </condition>
            22 <fail unless="compile-success"
            23        message="${compiled-info}"/>
            24    </target>

            我們來詳細(xì)分析一下上面的代碼。
            第1行是任務(wù)定義,在此不過多解釋。
            2-4行是任務(wù)定義和準(zhǔn)備工作,主要是建立編譯生成目錄和清理舊的輸出文件。
            5-12行便是命令行編譯的主要代碼,我們來逐個(gè)解釋。
            第5行定義了一個(gè)exec標(biāo)簽,用來調(diào)用devenv命令,并指定了編譯所在當(dāng)前目錄dir屬性,和操作系統(tǒng)信息os屬性。
            從第6行開始則為devenv命令的參數(shù)部分。
            其中第6行指定了要編譯的解決方案。
            第7行標(biāo)明該解決方案要進(jìn)行重新編譯。
            第8行指定了編譯類型為release模式。
            第9行指定編譯器使用 PATH、INCLUDE、LIBPATH 和 LIB 環(huán)境變量。
            第10行指定了編譯信息輸出的文件位置。由于devenv命令執(zhí)行完畢后,ANT無法從命令行獲取編譯信息,所以不能使用exec的output屬性來指定輸出位置(在調(diào)用Delphi編譯器的時(shí)候,ANT可以正常獲取編譯信息,因此output屬性有效),只能使用編譯器所具有的參數(shù)功能將信息輸出,該信息為判斷編譯成功與否的關(guān)鍵。
            14-15行讀取了上述的編譯信息文件的內(nèi)容,以便之后判斷編譯是否成功。
            17-21行則定義了一個(gè)編譯結(jié)果,用于判斷編譯是否成功。結(jié)果使用了contains屬性來判斷,如果輸出文件中包含字符串“0 已失敗”,則說明編譯成功完成。
            22-23行則是指示了ANT,一旦編譯失敗,則打印出編譯信息。
            當(dāng)然,這里只介紹了編譯VS.NET工程的其中一種方法,在此拋磚引玉。既然ANT為我們提供了如此強(qiáng)大的系統(tǒng)命令執(zhí)行功能,那么我們便可以在各種編程語言環(huán)境中游刃有余了。
            posted @ 2010-04-09 16:39 暗夜教父 閱讀(553) | 評(píng)論 (0)編輯 收藏

            一、簡(jiǎn)介:
              現(xiàn)在我們安裝Linux的時(shí)候通常考慮到安全因素(默認(rèn)情況下)是不打開telnet服務(wù)的,而ssh服務(wù)是有的,ant很早就支持telnet,但要求我們?cè)贚inux下要安裝telnet-server,并要啟用該服務(wù)。

            還好自Ant1.60開始支持了SSH 及SCP 操作了,早在Ant之前若要支持SSH、SCP、SFTP等任務(wù)就必須下載j2ssh的j2ssh-ant.jar和j2ssh-core.jar(在http://www.sourceforge.net的j2ssh下有下載)。現(xiàn)在可以使用Ant提供的Sshexec和scp任務(wù),由$ANT_HOME/lib/ant-jsch.jar提供支持,但是同樣你也要在http://www.jcraft.com/jsch/index.html下載一個(gè)依賴包jsch-0.1.24.jar(文件名因版本而不同),jsch同樣也是http://www.sourceforge.net下的一個(gè)項(xiàng)目。

            你需要把下載的jsch-0.1.24拷貝到$ANT_HOME/lib下,如果是Eclipse下的Ant環(huán)境必須在Window->Preferences->Ant->Runtime->Classpath中加入jsch-0.1.24。

            JSch是一個(gè)SSH2的純Java實(shí)現(xiàn)
            JSch允許你連接到sshd server并采用端口映射, X11 映射; Scp文件傳輸?shù)龋憧梢园鸭蒍Sch提供的功能到你自己的Java項(xiàng)目中,JSch 的授權(quán)方式為 BSD形式。

            二、簡(jiǎn)單例子:
              下面是用JSch完成Sshexec和scp兩個(gè)任務(wù)的最簡(jiǎn)單例子,如果需要更詳細(xì)的內(nèi)容,請(qǐng)參考Ant用戶手冊(cè)

            [Sshexec任務(wù)]
            <BR><target name="sshexec">
                  <sshexec host="192.168.122.180" username="root"  password="123456"
                     trust="true" command="cd /;ls"/>
            </target>

            注意上面的trust屬性一般設(shè)置為true, 如果為默認(rèn)值false時(shí),那么就要求你所連接的host必須存在于你的knownhosts文件中,并且這個(gè)文件也必須是存在的,否則會(huì)出現(xiàn) com.jcraft.jsch.JSchException: reject HostKey: 192.168.122.180異常。執(zhí)行Linux下的命令時(shí)可以用分號(hào)";"把多個(gè)命令隔開,它們將會(huì)依次執(zhí)行,而不需要寫多個(gè)sshexec進(jìn)行多次連接,每次連接只執(zhí)行一個(gè)命令。

            該任務(wù)的執(zhí)行后輸出結(jié)果如下:

            sshexec:
              [sshexec] Connecting to 192.168.122.180:22
              [
            sshexec] backup
              [
            sshexec] bin
              [
            sshexec] boot
              [
            sshexec] dev
              [
            sshexecetc
              ...................

            [scp任務(wù)]

            1.拷貝單個(gè)文件到遠(yuǎn)端服務(wù)器
            <scp file="c:/cmd.txt" todir="root:123456@192.168.122.180:/tmp" trust="true"/>

            <scp file="c:/cmd.txt" todir="root@192.168.122.180:/tmp" password="123456" trust="true"/>

            2.拷貝遠(yuǎn)端文件本地
            <scp file="root:123456@192.168.122.180:/tmp/cmd.txt" todir="D:/my-app"  trust="true"/>

            3.拷貝遠(yuǎn)端目錄到本地,將以遞歸形式操作
            <scp file="root:123456@192.168.122.180:/tmp/*" todir="d:/my-app" trust="true"/>

            4.拷貝本地目錄中的內(nèi)容到遠(yuǎn)端,遞歸形式,但不在服務(wù)器上建立my-app目錄
            <scp todir="root:123456@192.168.122.180:/tmp/" trust="true">
               
            <fileset dir="d:/my-app"/>
            </scp>

            5.拷貝一系列的文件到遠(yuǎn)端,會(huì)建立相應(yīng)的層次目錄,不建立my-app目錄
            <scp todir="root:123456@192.168.122.180:/tmp" trust="true">
               
            <fileset dir="d:/my-app">
                  
            <include name="**/*.java" />
               
            </fileset>
            </scp>

            <scp todir="root:123456@192.168.122.180:/tmp" trust="true">
               
            <fileset dir="d:/my-app" excludes="**/*.java"/>
            </scp>

            最后一個(gè)任務(wù)的執(zhí)行輸出結(jié)果如下(其他略):

            scp:
                  [scp]Connecting to 192.168.122.180:22
                  [
            scp] Sending: cmd.txt : 0
                  [
            scp] File transfer time: 0.0 Average Rate: ? B/s
                  [
            scp] Sending: pom.xml : 852
                  [
            scp] File transfer time: 0.0 Average Rate: ∞ B/s
                  [
            scp] Sending: application.properties : 142
                  [
            scp] File transfer time: 0.0 Average Rate: ∞ B/s
                  [
            scp] Sending: application.properties : 45
                  [
            scp] File transfer time: 0.0 Average Rate: ∞ B/s
                  [
            scp] Sending: test.properties : 0
                  [
            scp] File transfer time: 0.02 Average Rate: 0.0 B/s
                  [
            scp] Sending: application.properties : 153
                  [
            scp] File transfer time: 0.0 Average Rate: ∞ B/s
                  [
            scp] Sending: application.properties : 45
                  [
            scp] File transfer time: 0.0 Average Rate: ∞ B/s
                  [
            scp] done.

            三、其他例子:

            例子1:
            <?xml   version= "1.0 "?> 
            <project   name= "buildssh "   default= "DEFAULT "   basedir= ". "> 
            <target   name= "init "> 
            <!--   set   properties,   mkdir,   etc.   --> 
            <property   file= "build.properties "   /> 
            <property   name= "this.project "   value= "buildssh "   /> 
            <echo   message= "init   in   ${this.project} "   /> 
            <tstamp   /> 
            </target> 

            <target   name= "DEFAULT "   depends= "init "> 
            <echo   message= "connecting   to   ${build.server} "   /> 
            <sshexec   host= "Linux   server   IP   address "   username= "Linux   server     username "   password= "Linux   server   password "   trust= "true "   command= "Command   you   want   to   run   on   the   server "   /> 
            </target> 
            </project>

            例子2:
            import   com.jcraft.jsch.Channel;       
            import   com.jcraft.jsch.ChannelSftp;       
            import   com.jcraft.jsch.JSch;       
            import   com.jcraft.jsch.Session;       
            import   com.jcraft.jsch.UserInfo;       
                
            public   class   ExecSCP   {       
                    public   static   final   UserInfo   defaultUserInfo   =   new   UserInfo(){       
                            public   String   getPassphrase()   {       
                                    return   null;       
                            }       
                
                            public   String   getPassword()   {       
                                    return   null;       
                            }       
                
                            public   boolean   promptPassword(String   arg0)   {       
                                    return   false;       
                            }       
                
                            public   boolean   promptPassphrase(String   arg0)   {       
                                    return   false;       
                            }       
                
                            public   boolean   promptYesNo(String   arg0)   {       
                                    return   true;       
                            }       
                
                            public   void   showMessage(String   arg0)   {       
                            }       
                    };       
                
                    /**     
                      *   @param   args     
                      */     
            public   static   void   main(String[]   args)   throws   Exception{ 
            String   hostname   =   "www.mozat.com "; 
            String   username   =   "wiimii "; 
            String   password   =   "jtev000 "; 
            String   remoteFile   =   "Setup.ini "; 
            String   localFile   =   "C:\\ "; 

                            JSch   jsch=new   JSch(); 

                            Session   session=jsch.getSession(username,   hostname,   990); 
                            session.setPassword(password); 
                            session.setUserInfo(defaultUserInfo); 
                            session.connect(); 

                            Channel   channel=session.openChannel( "sftp ");       
                            channel.connect();       
                            ChannelSftp   c=(ChannelSftp)channel;       
                                  
                            c.get(remoteFile,   localFile);   
                            
                            session.disconnect(); 
                          } 

            posted @ 2010-04-09 16:29 暗夜教父 閱讀(2839) | 評(píng)論 (0)編輯 收藏

            這段ant腳本主要作用就是:自動(dòng)從SVN庫(kù)拉最新的代碼,編譯、并自動(dòng)部署到測(cè)試服務(wù)器。

             

            其中用到了“antsvn” ,有3個(gè)jar包需要配置進(jìn)去


            <?xml version="1.0" encoding="UTF-8"?> <!-- wei.songw 2008.3.19 --> <project basedir="." name="smmail" default="auto"> <!-- all properties are in build.properties --> <property file="build.properties" /> <!--svn本身需要的運(yùn)行庫(kù) --> <path id="svnant.lib"> <pathelement location="${svnjavahl.jar}" /> <pathelement location="${svnant.jar}" /> <pathelement location="${svnClientAdapter.jar}" /> </path> <!--java EE 1.4 庫(kù) --> <path id="javaEE1.4"> <fileset dir="${javaEE1.4.lib}"> <include name="**/*.jar" /> </fileset> </path> <!--項(xiàng)目的classpath庫(kù) --> <path id="project.classpath"> <pathelement location="${build.dir}" /> <fileset dir="${lib.dir}" /> </path> <!--清理項(xiàng)目任務(wù)(干掉下載目錄,tomcat原來的部署文件) --> <target name="clear"> <delete dir="${work.space}" /> <delete dir="${tomcat.home}/work/Catalina/localhost/${ant.project.name}" /> <delete dir="${tomcat.home}/webapps/${ant.project.name}" /> <delete dir="${tomcat.home}/webapps/${ant.project.name}.war" /> </target> <!-- load the svn task --> <taskdef name="svn" classname="org.tigris.subversion.svnant.SvnTask" classpathref="svnant.lib" /> <!--svn同步任務(wù)--> <target name="svn" depends="clear"> <mkdir dir="${work.space}"/> <svn username="SongWei" password="Song" javahl="false"> <checkout url="${urlRepos}" destPath="${work.space}" /> </svn> </target> <!--編譯--> <target name="compile" depends="svn" description="======compile project======"> <echo message="compile==========>${ant.project.name}: ${ant.file}" /> <mkdir dir="${build.dir}" /> <copy includeemptydirs="false" todir="${build.dir}"> <fileset dir="${java.source}" excludes="**/*.launch, **/*.java, config/*.*"/> </copy> <copy includeemptydirs="false" todir="${build.dir}"> <fileset dir="${java.config}" excludes="**/*.launch, **/*.java"/> </copy> <javac includejavaruntime="true" debug="true" debuglevel="${debuglevel}" destdir="${build.dir}" source="${source}" target="${target}" encoding="utf-8"> <src path="${java.source}" /> <exclude name="config/"/> <classpath> <path refid="project.classpath"> </path> <path refid="javaEE1.4"> </path> </classpath> </javac> <javac debug="true" debuglevel="${debuglevel}" destdir="${build.dir}" source="${source}" target="${target}" encoding="utf-8"> <src path="${java.config}" /> </javac> </target> <!--壓縮,打包--> <target name="war" depends="compile" description="======compress j2ee war file======"> <mkdir dir="${dist.dir}" /> <!--compress j2ee war file--> <war destfile="${war.file}" webxml="${web.dir}/WEB-INF/web.xml"> <fileset dir="${web.dir}" /> <classes dir="${build.dir}" /> <lib dir="${lib.dir}" /> </war> </target> <!--shutdowntomcat--> <target name="shutdowntomcat" description="========shutdowntomcat==========="> <exec executable="${tomcat.home}/bin/shutdown.sh" failonerror="false"></exec> <sleep seconds="10"/> </target> <!--startuptomcat--> <target name="startuptomcat" description="========startuptomcat==========="> <sleep seconds="5"/> <exec executable="${tomcat.home}/bin/startup.sh" failonerror="false"></exec> </target> <!--部署到tomcat下面克--> <target name="deploy" depends="war"> <copy file="${war.file}" todir="${tomcat.home}/webapps" /> </target> <!--全自動(dòng)無敵部署,啟動(dòng)關(guān)閉tomcat--> <target name="auto" depends="shutdowntomcat,deploy,startuptomcat"> <echo message="DONE!!!!" /> </target> </project>


            下面是build.xml指定的properties文件,需要和build.xml放在同一個(gè)目錄下面

            需要指定work.space(svn拉下來代碼的存放,已經(jīng)編譯,打包用的臨時(shí)目錄)

            tomcat.hometomcat服務(wù)器的根目錄,如果是其他服務(wù)器,需要修改對(duì)應(yīng)項(xiàng)

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

            build.version=1.0.0

            svnant.jar=/usr/java/svn/svnant.jar
            svnClientAdapter.jar=/usr/java/svn/svnClientAdapter.jar
            svnjavahl.jar=/usr/java/svn/svnjavahl.jar
            javaEE1.4.lib=/usr/javaEE-1.4

            debuglevel=source,lines
            target=1.6
            source=1.6

            work.space=/home/gmail/workspace
            dist.dir=${work.space}

            build.dir=${work.space}/WebRoot/WEB-INF/classes
            lib.dir=${work.space}/WebRoot/WEB-INF/lib

            java.source=${work.space}/src
            java.config=${work.space}/src/config

            web.dir=${work.space}/WebRoot
            resource.dir=${work.space}/resources

            tomcat.home=/home/gmail/tomcat6
            war.file=${dist.dir}/${ant.project.name}.war

            urlRepos=svn://192.168.1.100/product/SMMAIL/Develop

            posted @ 2010-04-09 11:23 暗夜教父 閱讀(1832) | 評(píng)論 (0)編輯 收藏
            摘要:
              Subversion是越來越被廣泛使用的版本管理工具,使用Ant腳本從Subversion獲取代碼,實(shí)現(xiàn)Daily Build。
              1.Subversion概述
              先引用Version Control with Subversion 中開頭的話:
              “If C gives you enough rope to hang yourself, think of Subversion as a sort of rope storage facility.” 
               —Brian W. Fitzpatrick
              然后告訴大家CVS是舊愛,Subversion是新歡。列舉若干Subversion的特性和優(yōu)勢(shì)為證,懶得寫了,直接看這里:Subversion的老家
              關(guān)于如何使用Subversion以及相關(guān)客戶端軟件,網(wǎng)上慢慢看吧,官方自由圖書不錯(cuò)。
              2.螞蟻出場(chǎng)
              團(tuán)隊(duì)最近的項(xiàng)目中即使用Subversion作為版本控制工具。Daily Build過兩天就得搭建起來了,上螞蟻!
              Tigris.org提供了Subclipse,SvnClientAdapter和SvnAnt。(見這里)
              Subclipse是一個(gè)Eclipse的插件,實(shí)現(xiàn)了IDE與Subversion得集成;
              SvnClientAdapter是Subversion的一套Java API,封裝了客戶端對(duì)Subversion的一些訪問操作;
              SvnAnt是用于訪問Subversion的Ant任務(wù),其依賴于SvnClientAdapter。
              我要用的就是SvnAnt,用SVN Check Out一份SvnAnt的代碼:
               
               
               
               
               svn co http://subclipse.tigris.org/svn/subclipse/trunk/svnant/ svnant
               
               
               
               
              在這個(gè)工程里面還包括svnant的Ant Task使用說明文檔,也可以在這里直接查看。
              使用其中的build.xml編譯SvnAnt后,在新生成的build子目錄下會(huì)生成svnant.jar。按照官方文檔的說法,把這個(gè)svnant.jar和SvnAnt工程的lib目錄下的svnClientAdapter.jar和svnjavahl.jar拷貝到Ant的目錄下即可。然后編寫如下的Ant腳本進(jìn)行測(cè)試:
               
               
               
               
               <?xml version="1.0"?>
               <project name="SVN Ant Test" default="checkout" basedir=".">
               <!-- 1 -->
               <property name="remote.url"
               value="svn://16.157.xxx.xxx/trunk/LNPORTAL/src/P3UIPAdapter/" />
               <property name="local.dir" value="local" /> 
               <!-- 2 -->
               <taskdef name="svn" classname="org.tigris.subversion.svnant.SvnTask" />
               <target name="prepare"
               description="Prepare the dirs for other tasks">
               <delete dir="${local.dir}" />
               <mkdir dir="${local.dir}" />
               </target>
               <!-- 3-->
               <target name="checkout" depends="prepare">
               <svn javahl="true" username="lihq" password="password" >
               <checkout url="${remote.url}" destPath="${local.dir}" />
               </svn>
               </target>
               </project>
               
               
               
               
              測(cè)試結(jié)果暫時(shí)不重要。
              3.JavaSVN出場(chǎng)
              SvnAnt的執(zhí)行依賴SvnClientAdapter,而執(zhí)行訪問SVN時(shí)又有兩種形式:其一是通過SVN 命令行程序的形式進(jìn)行的(我在想:如果是這樣,還不如使用Ant的exec任務(wù)呢);其二是通過Javahl來執(zhí)行的。
              Javahl是一個(gè)用于訪問Subversion的Java接口(估計(jì)是JNI),這需要Windows機(jī)上有svnjavahl.dll才行。團(tuán)隊(duì)的Daily Build的并不是Windows,于是求助JavaSVN,這是一個(gè)純Java的SVN解決方案。
              請(qǐng)?jiān)L問這個(gè)Guide:Making SvnAnt use JavaSVN
              我的實(shí)際步驟如下:
              Step 1:從Ant的lib目錄下移除SvnClientAdapter.jar,我沒有發(fā)現(xiàn)javahl.jar,于是便移除了svnjavahl.jar,其實(shí)移不移后者無所謂;
              Step 2:在剛才那個(gè)頁(yè)面下載javasvn.jar和javasvn-javahl.jar,以及JavaSVN的svnClientAdapter-0.9.32.jar。并把這三個(gè)jar都拷貝到Ant的lib目錄下;
              然后運(yùn)行上面寫的SVN Ant測(cè)試腳本,結(jié)果如下:
               
               
               
               …
               BUILD FAILED
               java.lang.AbstractMethodError: org.tigris.subversion.svnant.Feedback.logRevision(J)V
               
               Total time: 7 seconds
               
               
               
              雖然SVN的代碼都取下來了,但最后Ant會(huì)拋出一個(gè)如上的錯(cuò),這會(huì)使得Ant腳本無法運(yùn)行后面的任務(wù)。
              4.Thanks Open Source
              看來,大概是JavaSVN用自己的svnClientAdapter-0.9.32.jar改變了SVNAnt本來對(duì)調(diào)用。SVNAnt(by Tigris.org)原先是調(diào)用svnjavahl.jar來運(yùn)行SVN命令的。替換svnClientAdapter-0.9.32.jar后,SVNAnt(plus JavaSVN)是調(diào)用javasvn-javahl.jar和javasvn.jar來運(yùn)行SVN命令的。上面那個(gè)錯(cuò)誤大概就是兩套svnClientAdapter對(duì)某個(gè)抽象方法的定義不完全一致造成的,估計(jì)是API版本對(duì)應(yīng)的問題。解決如下:
              首先查看svnant.jar的源代碼,發(fā)現(xiàn)org.tigris.subversion.svnant.Feedback是實(shí)現(xiàn)svnClientAdapter.jar中的一個(gè)名為ISVNNotifyListener的接口。這個(gè)接口中對(duì)報(bào)錯(cuò)的logRevision方法的定義是:
               
               
               
               
               public abstract void logRevision(long revision, String path)
               
               
               
               
              而查看svnClientAdapter-0.9.32.jar中的ISVNNotifyListener的接口中的定義是:
               
               
               
               
               public abstract void logRevision(long revision)
               
               
               
               
              明顯不匹配,于是修改svnant.jar的源代碼,修改org.tigris.subversion.svnant.Feedback,象其中添加一個(gè)方法如下:
               
               
               
               
               //This method is added by Beegee
               public void logRevision(long revision) {
               }
               
               //This method is the original one by SVNANT
               public void logRevision(long revision, String path) {
               }
               
               
               
               
              然后重新編譯SVNAnt,生成svnant.jar,拷貝替換Ant 的lib目錄下的同名jar,重新運(yùn)行以上SVN Ant測(cè)試腳本,結(jié)果如下:
              

              OK!
              -end-
            posted @ 2010-04-09 11:20 暗夜教父 閱讀(515) | 評(píng)論 (0)編輯 收藏
            僅列出標(biāo)題  下一頁(yè)

            <2025年7月>
            293012345
            6789101112
            13141516171819
            20212223242526
            272829303112
            3456789

            常用鏈接

            留言簿(2)

            隨筆分類

            隨筆檔案

            文章分類

            文章檔案

            搜索

            •  

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            日韩AV无码久久一区二区 | 国产L精品国产亚洲区久久| 久久人人妻人人爽人人爽| 国内精品人妻无码久久久影院| 久久精品亚洲中文字幕无码麻豆| 久久99热精品| 亚洲国产一成久久精品国产成人综合 | 大蕉久久伊人中文字幕| 91精品久久久久久无码| 免费一级做a爰片久久毛片潮| 伊人久久大香线蕉综合Av| 秋霞久久国产精品电影院| 欧美亚洲国产精品久久| 999久久久免费国产精品播放| 无码任你躁久久久久久| 亚洲狠狠综合久久| 亚洲精品乱码久久久久久自慰| 亚洲狠狠综合久久| 精品国产乱码久久久久久郑州公司| 久久久久久久综合日本| 91精品日韩人妻无码久久不卡| 久久久久久极精品久久久| 青青草国产成人久久91网| 色欲综合久久躁天天躁蜜桃| 亚洲国产精品无码久久九九| 91久久精品视频| 久久久青草久久久青草| 国内精品伊人久久久久av一坑 | 亚洲中文字幕久久精品无码APP| 国产亚洲成人久久| 久久伊人精品青青草原高清| 欧美丰满熟妇BBB久久久| 久久精品日日躁夜夜躁欧美| 香蕉99久久国产综合精品宅男自 | 国产精品免费福利久久| 久久婷婷午色综合夜啪| 国产精品99久久久精品无码| 亚洲伊人久久综合中文成人网| 欧美国产精品久久高清| 无码人妻少妇久久中文字幕| 亚洲精品国产自在久久|