2006-6-24

嘗試以一個例子來說明搭建一個 project 時候的目錄構(gòu)建情況。

?

情況一

下面以一個地圖編輯器的例子為例

project mapeditor

父目錄是
”project mapeditor”,

.\Image 程序使用到的圖片。

.\Maps 程序運行時用戶保存的自定義地圖。

.\com 主程序 MapEditor.java 將會是用到的 package 的源文件。

.\com\cjren\swing\MyFilter.java

MapEditor.java 主程序源文件,代碼中沒有 ”package” 語句。

runMapEditor.bat 完成編譯和運行所需的所有工作。

?

下面主要看看 runMapEditor.bat 的內(nèi)容:

@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 這個文件夾中,這個文件夾是動態(tài)生成并且最后會被清楚掉的。

?

這里有三個值得注意的地方。

一,通過 ” javac -d .\build\classes MapEditor.java” ,不單只是 MapEditor.java 所定義的 class 都被放于 .\build\classes 中,甚至連 .\com MyFilter.java 所對應(yīng)的 class 也都在 .\build\classes\com\cjren\swing 中,而 com 包在 .\bulid\classes 下是自動被準(zhǔn)確生成的。也就是說所有的 .class 文件都被放在 .\bulid\classes 文件夾中了。

二,當(dāng)使用 ”java -cp .\build\classes MapEditor” 來運行程序的時候,并沒有因為 Image 文件夾不在 .\build\classes 而出錯。這說明了 .java 文件中的代碼已經(jīng)決定了它所使用到的 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” 下的所有東西都沒有改變,程序依然成功執(zhí)行。這就進(jìn)一步證明了 .java 文件中的代碼決定了所有其他目錄或文件元素的相對位置,這個位置以 .java 文件所在的目錄為標(biāo)準(zhǔn)。而與 .class 文件的路徑無關(guān)。但是:別混淆了 A.class 它所使用到的包的 .class 的路徑是以 A.class 文件的路徑為標(biāo)準(zhǔn)的?。?!這就與上面 MapEditor.class 也和(必須和) com 包同處于 bulid\classes 目錄下沒有矛盾。

?

情況二

目的是把上面情況一中所有的文件和文件夾都包含在 src 這個文件夾中,而 src 本身就是父目錄 project mapeditor2 下的一個文件夾。而且我希望編譯時候生成的 build 文件夾和 src 文件夾的關(guān)系是:

\project mapeditor2\src

\project mapeditor2\build



src
文件夾的內(nèi)容如下:

pj2-src
注意批處理文件
runMapEditor.bat src 文件夾下,而且在此情況下, runMapEditor.bat 的內(nèi)容將有所變化:

@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 和源代碼文件在同一個文件夾下。

?

情況三

嘗試在情況二的基礎(chǔ)上把 runMapEditor.bat 提到和 src 以及 build 相同的父目錄下。假設(shè)父目錄是 project mapeditor3 ,則:

pj3
現(xiàn)在
runMapEditor.bat 的內(nèi)容是:

@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

?

在嘗試工程當(dāng)中,發(fā)現(xiàn)以下的做法將找不到 Image 文件夾:

cd src

javac -d ..\build\classes MapEditor.java

cd ..

java -cp .\build\classes MapEditor

這種修改所造成的區(qū)別是運行 ”java” 命令的位置不同了。可以猜想是需要在 src 文件夾內(nèi)運行 java 命令,而 src 文件夾中含有所有程序所需的代碼和 image 素材。

?

下面提供一個稍微不同的批處理文件, runMapEditor2.bat ,它也同樣處于 project mapeditor3 這個父目錄下:

pj3-

runMapEditor2.bat
的內(nèi)容如下:

@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 文件都移到較遠(yuǎn)的地方 (d:\a) ,但是還可以成功運行。小結(jié)一下它能成功運行的特點:

一, src 文件夾中已經(jīng)包含了所有的元素,包括所需的外部 package 代碼,包括 image 文件夾。這些元素都必須使得主程序 .java 能成功的編譯。

二,運行 ”java” 命令都在 src 這個目錄下。也就是說都在和代碼處在相同的文件路徑下,而不是其他任何路徑。

?

情況一都三的小結(jié)

基本滿足了在 windows 系統(tǒng)下開發(fā)小項目的需求,我在這三個嘗試的例子中主程序 MapEditor.java 都沒有含有 ”package main” 這類的打包語句。