2006-6-24
嘗試以一個例子來說明搭建一個 project 時候的目錄構建情況。
情況一
下面以一個地圖編輯器的例子為例
父目錄是
”project mapeditor”,
.\Image : 程序使用到的圖片。
.\Maps : 程序運行時用戶保存的自定義地圖。
.\com : 主程序 MapEditor.java 將會是用到的 package 的源文件。
.\com\cjren\swing\MyFilter.java
MapEditor.java : 主程序源文件,代碼中沒有 ”package” 語句。
runMapEditor.bat : 完成編譯和運行所需的所有工作。
下面主要看看 runMapEditor.bat 的內容:
@echo off
rem output the date and time
date /T
time /T
echo welcome to my map editor :-)
rem make the directory for class files
mkdir .\build\classes
rem compile the source files
javac -d .\build\classes MapEditor.java
rem run the application,
rem but you must avoid this: java.\build\classes\MapEditor,
rem which will be an error
java -cp .\build\classes MapEditor
rem clean everything in the build folder
rmdir .\build /S /Q
pause
從上面的具體代碼中可以看出在編譯和運行的時候,所有的 class 文件都回被放在 .\build\classes 這個文件夾中,這個文件夾是動態生成并且最后會被清楚掉的。
這里有三個值得注意的地方。
一,通過 ” javac -d .\build\classes MapEditor.java” ,不單只是 MapEditor.java 所定義的 class 都被放于 .\build\classes 中,甚至連 .\com 中 MyFilter.java 所對應的 class 也都在 .\build\classes\com\cjren\swing 中,而 com 包在 .\bulid\classes 下是自動被準確生成的。也就是說所有的 .class 文件都被放在 .\bulid\classes 文件夾中了。
二,當使用 ”java -cp .\build\classes MapEditor” 來運行程序的時候,并沒有因為 Image 文件夾不在 .\build\classes 而出錯。這說明了 .java 文件中的代碼已經決定了它所使用到的 Image 文件夾的位置,這個位置是相對于 .java 文件所在的位置來說的,而不是 .class 。
三,我嘗試了在 d 盤下新建了一個 a 目錄,然后把
javac -d .\build\classes MapEditor.java
java -cp .\build\classes MapEditor
換成
javac -d d:\a MapEditor.java
java -cp d:\a MapEditor
之后,其他 ”project mapeditor” 下的所有東西都沒有改變,程序依然成功執行。這就進一步證明了 .java 文件中的代碼決定了所有其他目錄或文件元素的相對位置,這個位置以 .java 文件所在的目錄為標準。而與 .class 文件的路徑無關。但是:別混淆了 A.class 它所使用到的包的 .class 的路徑是以 A.class 文件的路徑為標準的!!!這就與上面 MapEditor.class 也和(必須和) com 包同處于 bulid\classes 目錄下沒有矛盾。
情況二
目的是把上面情況一中所有的文件和文件夾都包含在 src 這個文件夾中,而 src 本身就是父目錄 project mapeditor2 下的一個文件夾。而且我希望編譯時候生成的 build 文件夾和 src 文件夾的關系是:
\project mapeditor2\src
\project mapeditor2\build
src
文件夾的內容如下:
注意批處理文件
runMapEditor.bat
在
src
文件夾下,而且在此情況下,
runMapEditor.bat
的內容將有所變化:
@echo off
rem output the date and time
date /T
time /T
echo welcome to my map editor :-)
rem make the directory for class files
mkdir ..\build\classes
rem compile the source files
javac -d ..\build\classes MapEditor.java
rem run the application,
rem but you must avoid this: java.\build\classes\MapEditor,
rem which will be an error
java -cp ..\build\classes MapEditor
rem clean everything in the build folder
rmdir ..\build /S /Q
pause
情況一和情況二的差別不大,只是源代碼文件多一層的文件夾的包裹。而且最大的共同點是 runMapEditor.bat 和源代碼文件在同一個文件夾下。
情況三
嘗試在情況二的基礎上把 runMapEditor.bat 提到和 src 以及 build 相同的父目錄下。假設父目錄是 project mapeditor3 ,則:
現在
runMapEditor.bat
的內容是:
@echo off
rem output the date and time
date /T
time /T
echo welcome to my map editor :-)
rem make the directory for class files
mkdir .\build\classes
rem go into the src directory
cd src
rem compile the source files
javac -d ..\build\classes MapEditor.java
rem run the application,
rem but you must avoid this: java.\build\classes\MapEditor,
rem which will be an error
java -cp ..\build\classes MapEditor
rem clean everything in the build folder
rmdir ..\build /S /Q
pause
在嘗試工程當中,發現以下的做法將找不到 Image 文件夾:
cd src
javac -d ..\build\classes MapEditor.java
cd ..
java -cp .\build\classes MapEditor
這種修改所造成的區別是運行 ”java” 命令的位置不同了。可以猜想是需要在 src 文件夾內運行 java 命令,而 src 文件夾中含有所有程序所需的代碼和 image 素材。
下面提供一個稍微不同的批處理文件, runMapEditor2.bat ,它也同樣處于 project mapeditor3 這個父目錄下:
runMapEditor2.bat
的內容如下:
@echo off
mkdir d:\a
cd src
javac -d d:\a MapEditor.java
java -cp d:\a MapEditor
rmdir d:\a /S /Q
pause
這個修改過的例子把 class 文件都移到較遠的地方 (d:\a) ,但是還可以成功運行。小結一下它能成功運行的特點:
一, src 文件夾中已經包含了所有的元素,包括所需的外部 package 代碼,包括 image 文件夾。這些元素都必須使得主程序 .java 能成功的編譯。
二,運行 ”java” 命令都在 src 這個目錄下。也就是說都在和代碼處在相同的文件路徑下,而不是其他任何路徑。
情況一都三的小結
基本滿足了在 windows 系統下開發小項目的需求,我在這三個嘗試的例子中主程序 MapEditor.java 都沒有含有 ”package main” 這類的打包語句。