Appearance
Reading Classpath Resources
Many Java programs need to read configuration files at startup. For example, reading from a .properties
file:
java
String conf = "C:\\conf\\default.properties";
try (InputStream input = new FileInputStream(conf)) {
// TODO:
}
For this code to execute correctly, you must create a conf
directory on the C drive and place the default.properties
file inside. However, paths differ between Linux and Windows systems.
Therefore, reading configuration files from a fixed directory on the disk is not a good approach.
Is there a path-independent way to read files?
We know that directories where Java stores .class
files or jar packages can also include various other file types, such as:
- Configuration files, like
.properties
; - Image files, like
.jpg
; - Text files, such as
.txt
,.csv
; - …
Reading files from the classpath can avoid issues with inconsistent file paths in different environments. If we place the default.properties
file in the classpath, we don’t need to worry about its actual storage path.
Resources in the classpath always start with a /
. We can get the current Class object and call getResourceAsStream()
to directly read any resource file from the classpath:
java
try (InputStream input = getClass().getResourceAsStream("/default.properties")) {
// TODO:
}
One important point when calling getResourceAsStream()
is that it will return null
if the resource file does not exist. Therefore, we need to check if the returned InputStream is null
. If it is null
, it indicates that the resource file was not found in the classpath:
java
try (InputStream input = getClass().getResourceAsStream("/default.properties")) {
if (input != null) {
// TODO:
}
}
If we place the default configuration in the jar file and read an optional configuration file from the external file system, we can have both default configuration files and allow users to modify configurations:
java
Properties props = new Properties();
props.load(inputStreamFromClassPath("/default.properties"));
props.load(inputStreamFromFile("./conf.properties"));
This way of reading configuration files makes application startup more flexible.
Summary
- Storing resources in the classpath avoids file path dependencies.
- The Class object's
getResourceAsStream()
can read specified resources from the classpath. - When reading resources from the classpath, check if the returned InputStream is
null
.