简体   繁体   English

通过 getClass().getResource() 加载文件

[英]File loading by getClass().getResource()

I have followed the way of loading the resource file by using getClass.getResource(path) .我遵循了使用getClass.getResource(path)加载资源文件的方式。 The snippet of code is here :代码片段在这里:

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();

I have configured it in eclipse with the hierarchy (Under source there is a folder called SwingDemo. In SwingDemo there is my java file as well as the resource file)...我已经在 eclipse 中配置了它的层次结构(在源代码下有一个名为 SwingDemo 的文件夹。在 SwingDemo 中有我的 java 文件以及资源文件)...

  1. src源文件
    • SwingDemo摇摆演示
      1. CustomDialog.java自定义对话框
      2. Test.properties测试属性

When I am running this on eclipse everything is running fine.当我在 eclipse 上运行它时,一切都运行良好。 But as soon as I attempt to run the apps from cmd line null pointer exception is occuring..但是一旦我尝试从 cmd 行运行应用程序,就会发生空指针异常..

Command Line deployment hierarchy is as follows:命令行部署层次结构如下:

Folder : D:\\Work\\Java Progrms\\SwingDemo文件夹: D:\\Work\\Java Progrms\\SwingDemo

Hierarchy:等级制度:

  1. SwingDemo摇摆演示
    • CustomDialog.java自定义对话框
    • Test.properties测试属性

First of all I compiled this file inside SwingDemo folder from command line (javac CustomDialog.java ).首先,我从命令行 (javac CustomDialog.java ) 在SwingDemo文件夹中编译了这个文件。 Then I move one step back to Java Programs folder (as I mentioned the package inside .java class) and run the apps by using the famous然后我移一步回到 Java Programs 文件夹(正如我提到的 .java 类中的包)并使用著名的

java SwingDemo.CustomDialog

I used to follow similar steps when I used new FileInputStream("path") previously.以前使用 new FileInputStream("path") 时,我曾经遵循类似的步骤。 After doing this fashion I am getting null pointer exception..这样做之后,我得到了空指针异常..

I think getClass().getResource(url) cannot load file from a specific directory.我认为getClass().getResource(url)无法从特定目录加载文件。 That's why I put the resource in same directory as that of my java file.这就是为什么我将资源放在与我的 java 文件相同的目录中。 It ran fine in Eclipse.它在 Eclipse 中运行良好。 But why this is giving error when I run from Command Line.但是为什么当我从命令行运行时会出错。

getClass().getResource() uses the class loader to load the resource. getClass().getResource()使用类加载器来加载资源。 This means that the resource must be in the classpath to be loaded.这意味着资源必须在要加载的类路径中。

When doing it with Eclipse, everything you put in the source folder is "compiled" by Eclipse:使用 Eclipse 执行此操作时,您放在源文件夹中的所有内容都由 Eclipse“编译”:

  • .java files are compiled into .class files that go the the bin directory (by default) .java 文件被编译成 .class 文件进入 bin 目录(默认情况下)
  • other files are copied to the bin directory (respecting the package/folder hirearchy)其他文件被复制到 bin 目录(尊重包/文件夹结构)

When launching the program with Eclipse, the bin directory is thus in the classpath, and since it contains the Test.properties file, this file can be loaded by the class loader, using getResource() or getResourceAsStream() .使用 Eclipse 启动程序时,bin 目录因此位于类路径中,并且由于它包含 Test.properties 文件,因此类加载器可以使用getResource()getResourceAsStream()加载该文件。

If it doesn't work from the command line, it's thus because the file is not in the classpath.如果它在命令行中不起作用,则是因为该文件不在类路径中。

Note that you should NOT do请注意,您不应该这样做

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

to load a resource.加载资源。 Because that can work only if the file is loaded from the file system.因为只有从文件系统加载文件时才能工作。 If you package your app into a jar file, or if you load the classes over a network, it won't work.如果您将您的应用程序打包成一个 jar 文件,或者您通过网络加载类,它将无法工作。 To get an InputStream, just use要获得 InputStream,只需使用

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

And finally, as the documentation indicates,最后,正如文档所示,

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

will load a Test.properties file located in the same package as the class Foo.将加载与 Foo 类位于同一包中的 Test.properties 文件。

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

will load a Test.properties file located in the package com.foo.bar .将加载位于包com.foo.bar中的com.foo.bar文件。

The best way to access files from resource folder inside a jar is it to use the InputStream via getResourceAsStream .从 jar 中的资源文件夹访问文件的最佳方法是通过getResourceAsStream使用 InputStream 。 If you still need a the resource as a file instance you can copy the resource as a stream into a temporary file (the temp file will be deleted when the JVM exits):如果您仍然需要将资源作为文件实例,您可以将资源作为流复制到临时文件中(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;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM