JAR文件包及jar命令詳解

          常常在網上看到有人詢問:如何把?java?程序編譯成?.exe?文件。通常回答只有兩種,一種是制作一個可執行的?JAR?文件包,然后就可以像.chm?文檔一樣雙擊運行了;而另一種是使用?JET?來進行?編譯。但是?JET?是要用錢買的,而且據說?JET?也不是能把所有的?Java?程序都編譯成執行文件,性能也要打些折扣。所以,使用制作可執行?JAR?文件包的方法就是最佳選擇了,何況它還能保持?Java?的跨平臺特性。?

            下面就來看看什么是?JAR?文件包吧:?

            1.?JAR?文件包?

            JAR?文件就是?Java?Archive?File,顧名思意,它的應用是與?Java?息息相關的,是?Java?的一種文檔格式。JAR?文件非常類似?ZIP?文件??準確的說,它就是?ZIP?文件,所以叫它文件包。JAR?文件與?ZIP?文件唯一的區別就是在?JAR?文件的內容中,包含了一個?META-INF/MANIFEST.MF?文件,這個文件是在生成?JAR?文件的時候自動創建的。舉個例子,如果我們具有如下目錄結構的一些文件:?

            ==?

            `--?test?

             ?`--?Test.class?

            把它壓縮成?ZIP?文件?test.zip,則這個?ZIP?文件的內部目錄結構為:?

            test.zip?

            `--?test?

             ?`--?Test.class?

            如果我們使用?JDK?的?jar?命令把它打成?JAR?文件包?test.jar,則這個?JAR?文件的內部目錄結構為:?

            test.jar?

            |--?META-INF?

            | ?`--?MANIFEST.MF?

            `--?test?

              `--Test.class?

            2.?創建可執行的?JAR?文件包?

            制作一個可執行的?JAR?文件包來發布你的程序是?JAR?文件包最典型的用法。?

            Java?程序是由若干個?.class?文件組成的。這些?.class?文件必須根據它們所屬的包不同而分級分目錄存放;運行前需要把所有用到的包的根目錄指定給?CLASSPATH?環境變量或者?java?命令的?-cp?參數;運行時還要到控制臺下去使用?java?命令來運行,如果需要直接雙擊運行必須寫?Windows?的批處理文件?(.bat)?或者?Linux?的?Shell?程序。因此,許多人說,Java?是一種方便開發者苦了用戶的程序設計語言。?

            其實不然,如果開發者能夠制作一個可執行的?JAR?文件包交給用戶,那么用戶使用起來就方便了。在?Windows?下安裝?JRE?(Java?Runtime?Environment)?的時候,安裝文件會將?.jar?文件映射給?javaw.exe?打開。那么,對于一個可執行的?JAR?文件包,用戶只需要雙擊它就可以運行程序了,和閱讀?.chm?文檔一樣方便?(.chm?文檔默認是由?hh.exe?打開的)。那么,現在的關鍵,就是如何來創建這個可執行的?JAR?文件包。?

            創建可執行的?JAR?文件包,需要使用帶?cvfm?參數的?jar?命令,同樣以上述?test?目錄為例,命令如下:?

          jar?cvfm?test.jar?manifest.mf?test?

            這里?test.jar?和?manifest.mf?兩個文件,分別是對應的參數?f?和?m,其重頭戲在?manifest.mf。因為要創建可執行的?JAR?文件包,光靠指定一個?manifest.mf?文件是不夠的,因為?MANIFEST?是?JAR?文件包的特征,可執行的?JAR?文件包和不可執行的?JAR?文件包都包含?MANIFEST。關鍵在于可執行?JAR?文件包的?MANIFEST,其內容包含了?Main-Class?一項。這在?MANIFEST?中書寫格式如下:?

            Main-Class:?可執行主類全名(包含包名)?

            例如,假設上例中的?Test.class?是屬于?test?包的,而且是可執行的類?(定義了?public?static?void?main(String[])?方法),那么這個?manifest.mf?可以編輯如下:?

          Main-Class:?test.Test?<回車>?

            這個?manifest.mf?可以放在任何位置,也可以是其它的文件名,只需要有?Main-Class:?test.Test?一行,且該行以一個回車符結束即可。創建了?manifest.mf?文件之后,我們的目錄結構變為:?

            ==?

            |--?test?

            | ?`--?Test.class?

            `--?manifest.mf?

            這時候,需要到?test?目錄的上級目錄中去使用?jar?命令來創建?JAR?文件包。也就是在目錄樹中使用“==”表示的那個目錄中,使用如下命令:?

          jar?cvfm?test.jar?manifest.mf?test?

            之后在“==”目錄中創建了?test.jar,這個?test.jar?就是執行的?JAR?文件包。運行時只需要使用?java?-jar?test.jar?命令即可。?

            需要注意的是,創建的?JAR?文件包中需要包含完整的、與?Java?程序的包結構對應的目錄結構,就像上例一樣。而?Main-Class?指定的類,也必須是完整的、包含包路徑的類名,如上例的?test.Test;而且在沒有打成?JAR?文件包之前可以使用?java?<類名>?來運行這個類,即在上例中?java?test.Test?是可以正確運行的?(當然要在?CLASSPATH?正確的情況下)。?
           3.?jar?命令詳解?

            jar?是隨?JDK?安裝的,在?JDK?安裝目錄下的?bin?目錄中,Windows?下文件名為?jar.exe,Linux?下文件名為?jar。它的運行需要用到?JDK?安裝目錄下?lib?目錄中的?tools.jar?文件。不過我們除了安裝?JDK?什么也不需要做,因為?SUN?已經幫我們做好了。我們甚至不需要將?tools.jar?放到?CLASSPATH?中。?

            使用不帶任何的?jar?命令我們可以看到?jar?命令的用法如下:?

            jar?{ctxu}[vfm0M]?[jar-文件]?[manifest-文件]?[-C?目錄]?文件名?...?

            其中?{ctxu}?是?jar?命令的子命令,每次?jar?命令只能包含?ctxu?中的一個,它們分別表示:?

             -c 創建新的?JAR?文件包?

             -t 列出?JAR?文件包的內容列表?

             -x 展開?JAR?文件包的指定文件或者所有文件?

             -u 更新已存在的?JAR?文件包?(添加文件到?JAR?文件包中)?

               [vfm0M]?中的選項可以任選,也可以不選,它們是?jar?命令的選項參數?

             -v 生成詳細報告并打印到標準輸出?

             -f 指定?JAR?文件名,通常這個參數是必須的?

             -m 指定需要包含的?MANIFEST?清單文件?

             -0 只存儲,不壓縮,這樣產生的?JAR?文件包會比不用該參數產生的體積大,但速度更快?

             -M 不產生所有項的清單(MANIFEST〕文件,此參數會忽略?-m?參數?

               [jar-文件]?即需要生成、查看、更新或者解開的?JAR?文件包,它是?-f?參數的附屬參數?

               [manifest-文件]?即?MANIFEST?清單文件,它是?-m?參數的附屬參數?

               [-C?目錄]?表示轉到指定目錄下去執行這個?jar?命令的操作。它相當于先使用?cd?命令轉該目錄下再執行不帶?-C?參數的?jar?命令,它只能在創建和更新?JAR?文件包的時候可用。  ?

            文件名?...?指定一個文件/目錄列表,這些文件/目錄就是要添加到?JAR?文件包中的文件/目錄。如果指定了目錄,那么?jar?命令打包的時候會自動把該目錄中的所有文件和子目錄打入包中。?

            下面舉一些例子來說明?jar?命令的用法:?

            1)?jar?cf?test.jar?test?

            該命令沒有執行過程的顯示,執行結果是在當前目錄生成了?test.jar?文件。如果當前目錄已經存在?test.jar,那么該文件將被覆蓋。?

            2)?jar?cvf?test.jar?test?

            該命令與上例中的結果相同,但是由于?v?參數的作用,顯示出了打包過程,如下:?

            標明清單(manifest)?

            增加:test/(讀入=?0)?(寫出=?0)(存儲了?0%)?

            增加:test/Test.class(讀入=?7)?(寫出=?6)(壓縮了?14%)?

            3)?jar?cvfM?test.jar?test?

            該命令與?2)?結果類似,但在生成的?test.jar?中沒有包含?META-INF/MANIFEST?文件,打包過程的信息也略有差別:?

            增加:test/(讀入=?0)?(寫出=?0)(存儲了?0%)?

            增加:test/Test.class(讀入=?7)?(寫出=?6)(壓縮了?14%)?

            4)?jar?cvfm?test.jar?manifest.mf?test?

            運行結果與?2)?相似,顯示信息也相同,只是生成?JAR?包中的?META-INF/MANIFEST?內容不同,是包含了?manifest.mf?的內容?

            5)?jar?tf?test.jar?

            在?test.jar?已經存在的情況下,可以查看?test.jar?中的內容,如對于?2)?和?3)?生成的?test.jar?分別應該此命令,結果如下;?

            對于?2)?

            META-INF/?

            META-INF/MANIFEST.MF?

            test/?

            test/Test.class?

            對于?3)?

            test/?

            test/Test.class?

            6)?jar?tvf?test.jar?

            除顯示?5)?中顯示的內容外,還包括包內文件的詳細信息,如:?

            0?Wed?Jun?19?15:39:06?GMT?2002?META-INF/?

            86?Wed?Jun?19?15:39:06?GMT?2002?META-INF/MANIFEST.MF?

            0?Wed?Jun?19?15:33:04?GMT?2002?test/?

            7?Wed?Jun?19?15:33:04?GMT?2002?test/Test.class?

            7)?jar?xf?test.jar?

            解開?test.jar?到當前目錄,不顯示任何信息,對于?2)?生成的?test.jar,解開后的目錄結構如下:?

            ==?

            |--?META-INF?

            | ?`--?MANIFEST?

            `--?test?

              `--Test.class?

          jar?xvf?test.jar?

            運行結果與?7)?相同,對于解壓過程有詳細信息顯示,如:?

            創建:META-INF/?

            展開:META-INF/MANIFEST.MF?

            創建:test/?

            展開:test/Test.class?

            9)?jar?uf?test.jar?manifest.mf?

            在?test.jar?中添加了文件?manifest.mf,此使用?jar?tf?來查看?test.jar?可以發現?test.jar?中比原來多了一個?manifest。這里順便提一下,如果使用?-m?參數并指定?manifest.mf?文件,那么?manifest.mf?是作為清單文件?MANIFEST?來使用的,它的內容會被添加到?MANIFEST?中;但是,如果作為一般文件添加到?JAR?文件包中,它跟一般文件無異。?

            10)?jar?uvf?test.jar?manifest.mf?

            與?9)?結果相同,同時有詳細信息顯示,如:?

            增加:manifest.mf(讀入=?17)?(寫出=?19)(壓縮了?-11%)?

            4.?關于?JAR?文件包的一些技巧?

            1)?使用?unzip?來解壓?JAR?文件?

            在介紹?JAR?文件的時候就已經說過了,JAR?文件實際上就是?ZIP?文件,所以可以使用常見的一些解壓?ZIP?文件的工具來解壓?JAR?文件,如?Windows?下的?WinZip、WinRAR?等和?Linux?下的?unzip?等。使用?WinZip?和?WinRAR?等來解壓是因為它們解壓比較直觀,方便。而使用?unzip,則是因為它解壓時可以使用?-d?參數指定目標目錄。?

            在解壓一個?JAR?文件的時候是不能使用?jar?的?-C?參數來指定解壓的目標的,因為?-C?參數只在創建或者更新包的時候可用。那么需要將文件解壓到某個指定目錄下的時候就需要先將這具?JAR?文件拷貝到目標目錄下,再進行解壓,比較麻煩。如果使用?unzip,就不需要這么麻煩了,只需要指定一個?-d?參數即可。如:?

            unzip?test.jar?-d?dest/?

            2)?使用?WinZip?或者?WinRAR?等工具創建?JAR?文件?

            上面提到?JAR?文件就是包含了?META-INF/MANIFEST?的?ZIP?文件,所以,只需要使用?WinZip、WinRAR?等工具創建所需要?ZIP?壓縮包,再往這個?ZIP?壓縮包中添加一個包含?MANIFEST?文件的?META-INF?目錄即可。對于使用?jar?命令的?-m?參數指定清單文件的情況,只需要將這個?MANIFEST?按需要修改即可。?

            3)?使用?jar?命令創建?ZIP?文件?

            有些?Linux?下提供了?unzip?命令,但沒有?zip?命令,所以需要可以對?ZIP?文件進行解壓,即不能創建?ZIP?文件。如要創建一個?ZIP?文件,使用帶?-M?參數的?jar?命令即可,因為?-M?參數表示制作?JAR?包的時候不添加?MANIFEST?清單,那么只需要在指定目標?JAR?文件的地方將?.jar?擴展名改為?.zip?擴展名,創建的就是一個不折不扣的?ZIP?文件了,如將上一節的第?3)?個例子略作改動:?

            jar?cvfM?test.zip?test


          posted on 2006-08-09 16:23 nbt 閱讀(274) 評論(0)  編輯  收藏 所屬分類: Java2SE相關

          <2006年8月>
          303112345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          導航

          統計

          常用鏈接

          留言簿(3)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          相冊

          收藏夾

          Java技術網站

          友情鏈接

          國內一些開源網站

          最新隨筆

          搜索

          積分與排名

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 和政县| 平南县| 十堰市| 梅州市| 盘锦市| 凤山市| 博野县| 珲春市| 岳西县| 清流县| 松江区| 乐平市| 青铜峡市| 县级市| 海宁市| 浪卡子县| 上蔡县| 康保县| 郧西县| 龙陵县| 杭锦后旗| 万山特区| 巨鹿县| 岱山县| 岑溪市| 紫金县| 达尔| 庄河市| 化州市| 嘉峪关市| 北川| 马龙县| 兴宁市| 肇东市| 古田县| 海兴县| 施秉县| 潜山县| 且末县| 新津县| 亳州市|