2012-12-30 68 views
32

我遵循使用getClass.getResource(path)加載資源文件的方式。的代碼片段是在這裏:通過getClass()加載文件getResource()

String url = "Test.properties"; 

System.out.println("Before printing paths.."); 
System.out.println("Path2: "+ getClass().getResource(url).getPath()); 

FileInputStream inputStream = new FileInputStream(new File(getClass().getResource(url).toURI())); 
i_propConfig.load(inputStream); 
inputStream.close(); 

我已經在Eclipse中層次結構配置它(在源有一個名爲SwingDemo文件夾中SwingDemo有我的Java文件以及資源文件)。...

  1. SRC
    • SwingDemo
      1. CustomDialog.java
      2. Test.properties

當我在Eclipse上運行的一切,這是運行良好。但只要我嘗試從CMD行空指針異常的應用正在發生..

命令行部署層次結構如下所示:

文件夾:D:\Work\Java Progrms\SwingDemo

層次:

  1. SwingDemo
    • CustomDialog.java
    • Test.properties

所有我編譯的命令行SwingDemo文件夾內的文件(javac的CustomDialog.java)的第一個。然後,我移動一步回Java程序文件夾中(正如我前面提到的.java類裏面的包),並通過著名的

java SwingDemo.CustomDialog 

我曾經跟隨,當我用新的FileInputStream類似的措施(「路徑運行的應用程序「)。 做完這種方式後,我得到空指針例外..

我認爲getClass().getResource(url)無法加載文件從一個特定的目錄。這就是爲什麼我把資源放在與我的java文件相同的目錄中。它在Eclipse中運行良好。但是當我從命令行運行時,爲什麼會出現錯誤。

回答

61

getClass().getResource()使用類加載器來加載資源。這意味着資源必須位於要加載的類路徑中。

當與Eclipse這樣做,你把源文件夾中一切「編譯」的月蝕:

  • .java文件被編譯成。該走的bin目錄(默認)
  • 其他文件複製到bin目錄(尊重包/文件夾hirearchy)類文件

當使用Eclipse啓動程序,bin目錄因此在類路徑,並且由於它包含Test.properties文件,所以可以使用getResource()getResourceAsStream()通過類加載器加載此文件。

如果從命令行不起作用,則是因爲該文件不在類路徑中。

注意,你不應該做

FileInputStream inputStream = new FileInputStream(new File(getClass().getResource(url).toURI())); 

加載資源。因爲只有從文件系統加載文件時纔可以工作。如果您將應用程序打包成jar文件,或者如果您通過網絡加載這些類,它將無法工作。爲了得到一個InputStream,只是使用

getClass().getResourceAsStream("Test.properties") 

最後,作爲文件表明,

Foo.class.getResourceAsStream("Test.properties") 

將加載在同一封裝中類Foo一個Test.properties文件。

Foo.class.getResourceAsStream("/com/foo/bar/Test.properties") 

將加載位於封裝com.foo.bar一個Test.properties文件。

+2

幫我:「如果你包你的應用程序加入到一個jar文件中,或者如果你通過網絡加載這些類,它將無法工作。「 - >您需要從文件中獲取InputStream。 –

6

從jar中的資源文件夾訪問文件的最佳方法是使用InputStream通過getResourceAsStream。如果您還需要將資源作爲一個文件例如,您可以複製資源作爲流到一個臨時文件(當JVM退出臨時文件將被刪除):

public static File getResourceAsFile(String resourcePath) { 
    try { 
     InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream(resourcePath); 
     if (in == null) { 
      return null; 
     } 

     File tempFile = File.createTempFile(String.valueOf(in.hashCode()), ".tmp"); 
     tempFile.deleteOnExit(); 

     try (FileOutputStream out = new FileOutputStream(tempFile)) { 
      //copy stream 
      byte[] buffer = new byte[1024]; 
      int bytesRead; 
      while ((bytesRead = in.read(buffer)) != -1) { 
       out.write(buffer, 0, bytesRead); 
      } 
     } 
     return tempFile; 
    } catch (IOException e) { 
     e.printStackTrace(); 
     return null; 
    } 
} 
+0

非常有幫助的回答。我希望能夠多勞多得:D。我認爲它也可以使用這行代碼 InputStream in = getClass()。getResourceAsStream(resourcePath); – xXxpRoGrAmmErxXx

相關問題