JAVA獲取資源路徑、建立檔案物件
一、Java專案中建立檔案物件
下面是一個java專案,名稱為ResourceTest。在這個專案中有4個檔案,1.properties、2.properties、3.properties、4.properties。
編譯完成後,這4個檔案的路徑如下:
…ResourceTest/1.properties
…ResourceTest/bin/2.properties
…ResourceTest/bin/com/ghs/test/3.properties
…ResourceTest/bin/com/ghs/test/sub/4.properties
所以,我們可以通過下面的程式碼來為這4個檔案建立File物件,其中,”.”或者”./”表示當前目錄,也就是JVM的啟動目錄。
public class MainTest {
public static void main(String[] args) {
File file1 = new File("./1.properties");
//File file1 = new File("test1.txt");
File file2 = new File("./bin/2.properties");
//File file2 = new File("bin/2.properties");
File file3 = new File("./bin/com/ghs/test/3.properties" );
//File file3 = new File("bin/com/ghs/test/3.properties");
File file4 = new File("./bin/com/ghs/test/sub/4.properties");
//File file4 = new File("bin/com/ghs/test/sub/4.properties");
try {
System.out.println(file1.exists()+":"+file1.getCanonicalPath());
System.out .println(file2.exists()+":"+file2.getCanonicalPath());
System.out.println(file3.exists()+":"+file3.getCanonicalPath());
System.out.println(file4.exists()+":"+file4.getCanonicalPath());
} catch (IOException e) {
e.printStackTrace();
}
}
}
執行結果如下:
true:D:\me\open\open-project\ResourceTest\1.properties
true:D:\me\open\open-project\ResourceTest\bin\2.properties
true:D:\me\open\open-project\ResourceTest\bin\com\ghs\test\3.properties
true:D:\me\open\open-project\ResourceTest\bin\com\ghs\test\sub\4.properties
二、WEB專案中建立檔案物件
下面的是一個Java Web專案,名稱為ResourceWeb。這個專案下同樣有4個檔案:1.properties、2.properties、3.properties、4.properties。
編譯完成後,這4個檔案的路徑如下:
…/ResourceWeb/1.properties
…/ResourceWeb/build/classes/2.properties
…/ResourceWeb/build/classes/com/ghs/test/3.properties
…/ResourceWeb/build/classes/com/ghs/test/sub/4.properties
所以,我們可以通過下面的程式碼來建立web專案的檔案物件。
public class MainTest {
public static void main(String[] args) {
File file1 = new File("./1.properties");
//File file1 = new File("test1.txt");
File file2 = new File("./build/classes/2.properties");
//File file2 = new File("build/classes/2.properties");
File file3 = new File("./build/classes/com/ghs/test/3.properties");
//File file3 = new File("build/classes/com/ghs/test/3.properties");
File file4 = new File("./build/classes/com/ghs/test/sub/4.properties");
//File file4 = new File("build/classes/com/ghs/test/sub/4.properties");
try {
System.out.println(file1.exists()+":"+file1.getCanonicalPath());
System.out.println(file2.exists()+":"+file2.getCanonicalPath());
System.out.println(file3.exists()+":"+file3.getCanonicalPath());
System.out.println(file4.exists()+":"+file4.getCanonicalPath());
} catch (IOException e) {
e.printStackTrace();
}
}
}
執行結果如下:
true:D:\me\open\open-project\ResourceWeb\1.properties
true:D:\me\open\open-project\ResourceWeb\build\classes\2.properties
true:D:\me\open\open-project\ResourceWeb\build\classes\com\ghs\test\3.properties
true:D:\me\open\open-project\ResourceWeb\build\classes\com\ghs\test\sub\4.properties
細心的你肯定會發現,由於專案的性質不同,位置相同的檔案,路徑也會不一樣。不過,如果你再細心一點,還會發現,這種不一樣僅僅在於檔案編譯後的根目錄。
所以,為了保證資源讀取的統一性,Java提供了通用的資源讀取方式,使得我們不用關心專案編譯後文件的根目錄。他們就是通過類、類載入器讀取資源。
三、通過類/類載入器讀取資源
同樣是上面的Java專案,我們通過類載入器(ClassLoader)讀取資源,程式碼如下:
public class ClassLoaderReaderTest {
public static void main(String[] args) {
try {
ClassLoader loader = ClassReaderTest.class.getClassLoader();
File file2 = new File(loader.getResource("2.properties").toURI());
System.out.println(file2.exists()+":"+file2.getCanonicalPath());
File file3 = new File(loader.getResource("com/ghs/test/3.properties").toURI());
System.out.println(file3.exists()+":"+file3.getCanonicalPath());
File file4 = new File(loader.getResource("com/ghs/test/sub/4.properties").toURI());
System.out.println(file4.exists()+":"+file4.getCanonicalPath());
File file1 = new File(loader.getResource("../1.properties").toURI());
System.out.println(file1.exists()+":"+file1.getCanonicalPath());
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
執行結果如下:
true:D:\me\open\open-project\ResourceTest\bin\2.properties
true:D:\me\open\open-project\ResourceTest\bin\com\ghs\test\3.properties
true:D:\me\open\open-project\ResourceTest\bin\com\ghs\test\sub\4.properties
java.lang.NullPointerException
at com.ghs.test.ClassReaderTest.main(ClassReaderTest.java:17)
我們會發現,通過ClassLoader讀取資源的時候,當前路徑就是專案檔案編譯後的根目錄,對於普通Java專案而言,就是…/bin目錄,對於web專案而言,就是…/build/classes目錄。
但是,當我們在讀取第一個檔案的時候丟擲了異常,這並不是因為我們的路徑錯了,而是因為1.properties不在類載入的範圍之類。也就是說,類載入器能夠讀取到的資源僅僅侷限於編譯後的根目錄。
下面,我們再使用類(Class)來讀取資源,程式碼如下:
public class ClassLoaderReaderTest {
public static void main(String[] args) {
try {
Class clazz = ClassReaderTest.class;
File file2 = new File(clazz.getResource("/2.properties").toURI());
System.out.println(file2.exists()+":"+file2.getCanonicalPath());
File file3 = new File(clazz.getResource("3.properties").toURI());
System.out.println(file3.exists()+":"+file3.getCanonicalPath());
File file4 = new File(clazz.getResource("sub/4.properties").toURI());
System.out.println(file4.exists()+":"+file4.getCanonicalPath());
File file1 = new File(clazz.getResource("../1.properties").toURI());
System.out.println(file1.exists()+":"+file1.getCanonicalPath());
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
執行結果如下:
true:D:\me\open\open-project\ResourceTest\bin\2.properties
true:D:\me\open\open-project\ResourceTest\bin\com\ghs\test\3.properties
true:D:\me\open\open-project\ResourceTest\bin\com\ghs\test\sub\4.properties
java.lang.NullPointerException
at com.ghs.test.ClassReaderTest.main(ClassReaderTest.java:17)
當我們通過類載入資源時,當前路徑就是當前類所在的路徑,對上面的例子來說,就是MainTest.class所在的路徑。當載入資源時,如果在路徑前面加上”/”,就跟通過ClassLoader載入資源時完全一樣的。
同樣的,通過類載入資源時,僅限於專案編譯後的根目錄下的資源。