2012-12-30 62 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

相关问题