Java - Read file from classpath
In this article you will learn how to read a file from the Java Classpath.
We have already explained What is a Java classpath? in the Java classpath article. In the article you're reading now, you will learn how to properly access files in your Classpath.
Table of Contents
On the image below we can see the architecture behind reading files from classpath in Java. Parts of the image are explained in detail in the following paragraphs.
1. How to setup the classpath
First we need to add a file to classpath. There are 2 possibilities for this:
- If the file that we want to read exists under a specific folder inside src (respectively bin or target folder), we usually do not need to do anything since the IDE does it for us by adding the files automatically to the compiled folder (usually bin or target)
- If the file that we want to be read is in a jar file, then we need to add jar file to our Classpath
Next (just to be sure) we are going to double check the build directory. To do that go here:
ProjectName > Properties > Java Build Path > Source tab
Now we can read resource file in Java.
2. How to read a file from the classpath with getClass().getResource()
Lets say that we have created Java project called ClasspathExample and we need to read example.xml from it, firstly we need to add resource folder to classpath and then read it.
package com.xenovation;
import java.io.File;
import java.net.URL;
public class ClasspathExample {
public File readFileFromClasspath() {
URL fileUrl = getClass().getResource("/example.xml");
return new File(fileUrl.getFile());
}
}
Here we used getClass().getResource(), this method is trying to read our file example.xml from the root "/" path of the classpath. In case the path does not start with "/", the file is getting searched in the same package of the class (in our example that would be "com.xenovation").
3. How to read a file from the classpath via ClassLoader
We can also use ClassLoader instance, we can obtain it by using getClass().getClassLoader(). It goes like this:
InputStream inputStream = getClass().getClassLoader().getResourceAsStream("example.xml");
String data = readFromInputStream(input Stream);
The main difference is that when we use getResourceAsStream on a ClassLoader instance, the path is treated as absolute starting from the root of the classpath. In any case it is recommended to always use absolute paths to access the file in the classpath.
4. Additional examples
Here is an example of using getClass().getResource() and ClassLoader:
package myTestPackage;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
public class Examples {
private static final String line = "-----------------------------------------";
private void loadResource (String resource) throws IOException {
URL u = this.getClass().getResource(resource);
loadResourceByUrl(u, resource);
}
private void loadResourceWithContextLoader (String resource) throws IOException {
URL u = Thread.currentThread().getContextClassLoader().getResource(resource);
loadResourceByUrl(u, resource);
}
private void loadResourceWithSystemClassLoader (String resource) throws IOException {
URL u = ClassLoader.getSystemClassLoader().getResource(resource);
loadResourceByUrl(u, resource);
}
private void loadResourceByUrl (URL u, String resource) throws IOException {
System.out.println("-> attempting input resource: "+resource);
if (u != null) {
String path = u.getPath();
path = path.replaceFirst("^/(.:/)", "$1");
System.out.println(" absolute resource path found :\n " + path);
String s = new String(Files.readAllBytes(Paths.get(path)));
System.out.println(" file content: "+s);
} else {
System.out.println(" no resource found: " + resource);
}
}
public static void main (String[] args) throws IOException {
Examples a = new Examples();
System.out.println(line+"\nusing this.getClass().getResource\n"+line);
a.loadResource("test-pkg-resource.txt");
a.loadResource("/test-pkg-resource.txt");
a.loadResource("root-resource.txt");
a.loadResource("/root-resource.txt");
System.out.println(line+"\n using current thread context loader\n"+line);
a.loadResourceWithContextLoader("test-pkg-resource.txt");
a.loadResourceWithContextLoader("/test-pkg-resource.txt");
a.loadResourceWithContextLoader("root-resource.txt");
a.loadResourceWithContextLoader("/root-resource.txt");
System.out.println(line+"\n using ClassLoader.getSystemClassLoader()\n"+line);
a.loadResourceWithSystemClassLoader("test-pkg-resource.txt");
a.loadResourceWithSystemClassLoader("/test-pkg-resource.txt");
a.loadResourceWithSystemClassLoader("root-resource.txt");
a.loadResourceWithSystemClassLoader("/root-resource.txt");
}
}
The output looks like this:
-----------------------------------------
using this.getClass().getResource
-----------------------------------------
-> attempting input resource: test-pkg-resource.txt
absolute resource path found :
C:/load-resource/out/production/load-resource/com/logicbig/example/test-pkg-resource.txt file content: test file, local to package
-> attempting input resource: /test-pkg-resource.txt
no resource found: /test-pkg-resource.txt
-> attempting input resource: root-resource.txt
no resource found: root-resource.txt
-> attempting input resource: /root-resource.txt
absolute resource path found : C:/load-resource/out/production/load-resource/root-resource.txt file content: root test file
-----------------------------------------
using current thread context loader
-----------------------------------------
-> attempting input resource: test-pkg-resource.txt
no resource found: test-pkg-resource.txt
-> attempting input resource: /test-pkg-resource.txt
no resource found: /test-pkg-resource.txt
-> attempting input resource: root-resource.txt
absolute resource path found : C:/load-resource/out/production/load-resource/root-resource.txt file content: root test file
-> attempting input resource: /root-resource.txt
no resource found: /root-resource.txt
-----------------------------------------
using ClassLoader.getSystemClassLoader()
-----------------------------------------
-> attempting input resource: test-pkg-resource.txt
no resource found: test-pkg-resource.txt
-> attempting input resource: /test-pkg-resource.txt
no resource found: /test-pkg-resource.txt
-> attempting input resource: root-resource.txt
absolute resource path found : C:/load-resource/out/production/load-resource/root-resource.txt file content: root test file
-> attempting input resource: /root-resource.txt
no resource found: /root-resource.txt
In this example we first created a line which is used later in the program. After that we told the program to search for paths using get.Class().getResource, using thread context loader and by using ClassLoader.getSystemClassLoader(). If in one of those attempts programm found a path it would print out that the absolute resource path is found along with the path, if not it would simply say that the resource is not found.
More to read about handling files:
How to access files in Java
Read from File in Java
Write to File in Java