InputStream inputStream =
ClassLoader.getSystemClassLoader()
.getResource("pics/logo.jpg")
.openStream();
无论是getResource
还是openStream
都返回了null
。我该如何解决这个问题?
InputStream inputStream =
ClassLoader.getSystemClassLoader()
.getResource("pics/logo.jpg")
.openStream();
无论是getResource
还是openStream
都返回了null
。我该如何解决这个问题?
从*.jar
文件加载*.jpg
图像(或任何其他图像)使用以下模式:
Create a project, which then be compiled to the *.jar
file
project-with-resources
│
├── src
│ └── main
│ ├── java
│ │ ├── . . .
│ │ └── Project.java
│ └── resources
│ ├── . . .
│ └── image1.jpg
└── pom.xml
Configure maven-resources-plugin
(there may be several resources folders)
<build>
<defaultGoal>package</defaultGoal>
<resources>
<resource>
<directory>src/main/resources</directory>
<targetPath>resources</targetPath>
</resource>
. . .
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
</plugin>
. . .
</plugins>
</build>
In Java
code use ImageIO
class to read pictures to the BufferedImage
objects
public class Project {
public static void main(String[] args) throws IOException {
BufferedImage image =
ImageIO.read(Project.class
.getResourceAsStream("/resources/image1.jpg"));
}
}
Prepare getters, if necessary
public class Project {
private BufferedImage image;
. . .
public BufferedImage getImage() {
return image;
}
}
Build project to the *.jar
file using Maven package
goal in your IDE
java.lang.Class.getResource()
和java.lang.ClassLoader.getResource()
之间在资源名称的解释上有所不同:对于前者,给定的名称相对于类的包,除非它以'/'开头,对于后者给定的名称始终是"绝对的"。
这意味着当您调用java.lang.String.class.getResource("resource/Doc.jpg")
时,它将查找/java/lang/resource/Doc.jpg
,而调用java.lang.String.class.getClassLoader().getResource("resource/Doc.jpg")
则尝试查找/resource/Doc.jpg
。
两者都不是真正的“路径”(就文件系统上的位置而言),它们确定相对于CLASSPATH的位置。这个位置可以是文件系统上的位置(如果资源不在JAR文件中...),但它也可能是一个数据库记录的引用,提供为URI,这取决于所涉及的类加载器的实现。
我在Netbeans中使用Ant创建了一个Java应用程序,代码如下:
public class Main {
public static void main(String[] args){
System.out.println(ClassLoader.getSystemClassLoader().
getResource(".").getPath());
}
}
当我在Netbeans中运行时,我得到了:
/Users/enta/NetBeansProjects/JavaFrontEnd/JavaApplication47/build/classes/
但是如果我用命令行运行它:
java -jar "/Users/enta/NetBeansProjects/JavaFrontEnd/JavaApplication50/dist/JavaApplication50.jar"
我得到了:
Exception in thread "main" java.lang.NullPointerException at Main.main(Main.java:13)
奇怪;我没有深入研究它。然后我创建了一个使用Maven的Java应用程序,也是在Netbeans中,代码完全相同,当我运行它时,无论是在Netbeans内部还是外部,我都得到了正确的答案。从Netbeans内部:
------------------------------------------------------------------------
Building JavaApplication46 1.0-SNAPSHOT
------------------------------------------------------------------------
--- exec-maven-plugin:1.5.0:exec (default-cli) @ JavaApplication46 ---
/Users/enta/NetBeansProjects/JavaFrontEnd/JavaApplication46/target/classes/
------------------------------------------------------------------------
您需要将'logo.jpg'文件放置在'pics'目录中,相对于您的CLASSPATH根目录。否则,当您尝试基于此打开一个InputStream时,ClassLoader.getResource() 将返回null,并导致NPE。
因此,在使用此代码的Eclipse工作区时...
import java.io.InputStream;
import java.net.URL;
public class GetResource {
public static void main(String[] args) throws Exception {
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
URL resource = classLoader.getResource("pics/logo.jpg");
System.out.println("resource is " + resource);
InputStream inputStream = resource.openStream();
System.out.println("The inputStream was not null");
}
}
它将返回...
resource is null
Exception in thread "main" java.lang.NullPointerException
at GetResource.main(GetResource.java:9)
resource is file:/home/joe/workspace/Play/bin/pics/logo.jpg
The inputStream was not null
GetResource.class.getResource()
即可。使用 ClassName.class 的方式可能会有一些类加载器版本无法解决的问题。 - matt