Java – Read a file from resources folder
In Java, we can use getResourceAsStream
or getResource
to read a file or multiple files from a resources
folder or root of the classpath.
The getResourceAsStream
method returns an InputStream
.
// the stream holding the file content
InputStream is = getClass().getClassLoader().getResourceAsStream("file.txt");
// for static access, uses the class name directly
InputStream is = JavaClassName.class.getClassLoader().getResourceAsStream("file.txt");
The getResource
method returns an URL
and normally convert it to a File
; Not working in JAR file.
// get the file url, not working in JAR file.
URL resource = getClass().getClassLoader().getResource("file.txt");
if (resource == null) {
throw new IllegalArgumentException("file not found!");
} else {
// failed if files have whitespaces or special characters
//return new File(resource.getFile());
return new File(resource.toURI());
}
// for static access
// URL resource = JavaClassName.class.getClassLoader().getResource("fileName");
1. Files in resources folder
1.1 Review the files in the src/main/resources
, later we will access the files and print out the file content.
datasource.url=jdbc:mysql://localhost/mkyong?useSSL=false
datasource.username=root
datasource.password=password
datasource.driver-class-name=com.mysql.jdbc.Driver
{
"name": "mkyong",
"age": 38
}
{
"name": "jack",
"age": 40
}
{
"name": "sub",
"age": 99
}
1.2 By default, build tools like Maven, Gradle, or common Java practice will copy all files from src/main/resources
to the root of target/classes
or build/classes
. So, when we try to read a file from src/main/resources
, we read the file from the root of the project classpath.
1.3 Below is a JAR file structure. Usually, the files in the resources
folder will copy to the root of the classpath.
$ jar -tf target/example.jar
META-INF/MANIFEST.MF
META-INF/
json/
json/sub/
json/file2.json
json/sub/subfile1.json
json/file1.json
database.properties
com/
com/mkyong/
com/mkyong/io/
com/mkyong/io/utils/
//...
2. Get a file from the resources folder.
2.1 The below example demonstrates the use of getResourceAsStream
and getResource
methods to read a file json/file1.json
from the resources
folder and print out the file content.
Note
- The
getResource
method is not working in the JAR file. - The
getResourceAsStream
method works everywhere.
package com.mkyong.io.utils;
import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.List;
public class FileResourcesUtils {
public static void main(String[] args) throws IOException {
FileResourcesUtils app = new FileResourcesUtils();
//String fileName = "database.properties";
String fileName = "json/file1.json";
System.out.println("getResourceAsStream : " + fileName);
InputStream is = app.getFileFromResourceAsStream(fileName);
printInputStream(is);
System.out.println("\ngetResource : " + fileName);
File file = app.getFileFromResource(fileName);
printFile(file);
}
// get a file from the resources folder
// works everywhere, IDEA, unit test and JAR file.
private InputStream getFileFromResourceAsStream(String fileName) {
// The class loader that loaded the class
ClassLoader classLoader = getClass().getClassLoader();
InputStream inputStream = classLoader.getResourceAsStream(fileName);
// the stream holding the file content
if (inputStream == null) {
throw new IllegalArgumentException("file not found! " + fileName);
} else {
return inputStream;
}
}
/*
The resource URL is not working in the JAR
If we try to access a file that is inside a JAR,
It throws NoSuchFileException (linux), InvalidPathException (Windows)
Resource URL Sample: file:java-io.jar!/json/file1.json
*/
private File getFileFromResource(String fileName) throws URISyntaxException{
ClassLoader classLoader = getClass().getClassLoader();
URL resource = classLoader.getResource(fileName);
if (resource == null) {
throw new IllegalArgumentException("file not found! " + fileName);
} else {
// failed if files have whitespaces or special characters
//return new File(resource.getFile());
return new File(resource.toURI());
}
}
// print input stream
private static void printInputStream(InputStream is) {
try (InputStreamReader streamReader =
new InputStreamReader(is, StandardCharsets.UTF_8);
BufferedReader reader = new BufferedReader(streamReader)) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
// print a file
private static void printFile(File file) {
List<String> lines;
try {
lines = Files.readAllLines(file.toPath(), StandardCharsets.UTF_8);
lines.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Output
getResourceAsStream : json/file1.json
{
"name": "mkyong",
"age": 38
}
getResource : json/file1.json
{
"name": "mkyong",
"age": 38
}
2.2 Now, we pack the project into a JAR file and run it; this time, the getResource
will fail and returns either NoSuchFileException
or InvalidPathException
. We cannot read the files inside the JAR file via the resource URL.
Run the JAR file on Linux (Ubuntu), it throws NoSuchFileException
.
$ mvn clean package
$ java -jar target/java-io.jar
getResourceAsStream : json/file1.json
{
"name": "mkyong",
"age": 38
}
# for new File(resource.getFile());
getResource : json/file1.json
java.nio.file.NoSuchFileException: file:/home/mkyong/projects/core-java/java-io/target/java-io.jar!/json/file1.json
at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:92)
at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111)
at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:116)
at java.base/sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:219)
at java.base/java.nio.file.Files.newByteChannel(Files.java:370)
at java.base/java.nio.file.Files.newByteChannel(Files.java:421)
at java.base/java.nio.file.spi.FileSystemProvider.newInputStream(FileSystemProvider.java:420)
at java.base/java.nio.file.Files.newInputStream(Files.java:155)
at java.base/java.nio.file.Files.newBufferedReader(Files.java:2838)
at java.base/java.nio.file.Files.readAllLines(Files.java:3329)
at com.mkyong.io.utils.FileResourcesUtils.printFile(FileResourcesUtils.java:135)
at com.mkyong.io.utils.FileResourcesUtils.main(FileResourcesUtils.java:24)
# for new File(resource.toURI());
getResource : json/file1.json
Exception in thread "main" java.lang.IllegalArgumentException: URI is not hierarchical
at java.base/java.io.File.<init>(File.java:420)
at com.mkyong.io.utils.FileResourcesUtils.getFileFromResource(FileResourcesUtils.java:112)
at com.mkyong.io.utils.FileResourcesUtils.main(FileResourcesUtils.java:29)
Run the JAR file on Windows, it throws InvalidPathException
.
$ mvn clean package
$ java -jar target/java-io.jar
getResourceAsStream : json/file1.json
{
"name": "mkyong",
"age": 38
}
getResource : json/file1.json
Exception in thread "main" java.nio.file.InvalidPathException:
Illegal char <:> at index 4: file:\C:\Users\mkyong\projects\core-java\java-io\target\java-io.jar!\json\file1.json
at java.base/sun.nio.fs.WindowsPathParser.normalize(WindowsPathParser.java:182)
at java.base/sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:153)
at java.base/sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:77)
at java.base/sun.nio.fs.WindowsPath.parse(WindowsPath.java:92)
at java.base/sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:229)
at java.base/java.io.File.toPath(File.java:2290)
at com.mkyong.io.utils.FileResourcesUtils.printFile(FileResourcesUtils.java:166)
at com.mkyong.io.utils.FileResourcesUtils.main(FileResourcesUtils.java:32)
P.S This example uses the Maven plugin maven-jar-plugin
to create the JAR file.
<!-- Make this jar executable -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.mkyong.io.utils.FileResourcesUtils</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
3. Get a file from the resources folder – Unit Test
3.1 We put the test resources at folder src/test/resources
for unit tests. Usually, the files in test resources will copy to the target/test-classes
folder.
{
"name": "unit test",
"age": 38
}
datasource.url=jdbc:mysql://localhost/test?useSSL=false
datasource.username=test
datasource.password=password
datasource.driver-class-name=com.mysql.jdbc.Driver
3.2 It works the same way we read the file from src/main/resources
. We use the same getResourceAsStream
and getResource
methods to read the file from the src/test/resources
.
package com.mkyong.io;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.io.*;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.List;
// Unit test class
public class FileResourcesTest {
@DisplayName("Test loading a JSON file")
@Test
void loadJSONTest() {
String fileName = "json/file1.json";
ClassLoader classLoader = getClass().getClassLoader();
try (InputStream inputStream = classLoader.getResourceAsStream(fileName);
InputStreamReader streamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
BufferedReader reader = new BufferedReader(streamReader)) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
@DisplayName("Test loading a properties file")
@Test
void loadPropTest() throws IOException, URISyntaxException {
String fileName = "database.properties";
ClassLoader classLoader = getClass().getClassLoader();
URL resource = classLoader.getResource(fileName);
if (resource == null) {
throw new IllegalArgumentException("file not found! " + fileName);
}
//File file = new File(resource.getFile());
File file = new File(resource.toURI());
List<String> lines = Files.readAllLines(file.toPath(), StandardCharsets.UTF_8);
lines.forEach(System.out::println);
}
}
Output
{
"name": "unit test",
"age": 38
}
datasource.url=jdbc:mysql://localhost/test?useSSL=false
datasource.username=test
datasource.password=password
datasource.driver-class-name=com.mysql.jdbc.Driver
4. Get all files from a resource folder. (NON-JAR environment)
If we don’t know the exact filename and want to read all files, including sub-folder files from a resources folder, we can use the NIO Files.walk
to easily access and read the files.
4.1 The below example uses Files.walk
to read all files from a folder src/main/resources/json
:
package com.mkyong.io.utils;
import java.io.*;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.stream.Collectors;
public class FileResourcesUtils {
public static void main(String[] args) throws IOException {
FileResourcesUtils app = new FileResourcesUtils();
// read all files from a resources folder
try {
// files from src/main/resources/json
List<File> result = app.getAllFilesFromResource("json");
for (File file : result) {
System.out.println("file : " + file);
printFile(file);
}
} catch (URISyntaxException | IOException e) {
e.printStackTrace();
}
}
private List<File> getAllFilesFromResource(String folder)
throws URISyntaxException, IOException {
ClassLoader classLoader = getClass().getClassLoader();
URL resource = classLoader.getResource(folder);
// dun walk the root path, we will walk all the classes
List<File> collect = Files.walk(Paths.get(resource.toURI()))
.filter(Files::isRegularFile)
.map(x -> x.toFile())
.collect(Collectors.toList());
return collect;
}
// print a file
private static void printFile(File file) {
List<String> lines;
try {
lines = Files.readAllLines(file.toPath(), StandardCharsets.UTF_8);
lines.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Output
file : /home/mkyong/projects/core-java/java-io/target/classes/json/file1.json
{
"name": "mkyong",
"age": 38
}
file : /home/mkyong/projects/core-java/java-io/target/classes/json/file2.json
{
"name": "jack",
"age": 40
}
file : /home/mkyong/projects/core-java/java-io/target/classes/json/sub/subfile1.json
{
"name": "sub",
"age": 99
}
4.2 However, the standard Files.walk
in example 4.1 can’t access the files in the JAR file directly, try run the example 4.1 in a JAR environment, and it throws FileSystemNotFoundException
.
$ mvn clean package
$ java -jar target/java-io.jar
Exception in thread "main" java.nio.file.FileSystemNotFoundException
at jdk.zipfs/jdk.nio.zipfs.ZipFileSystemProvider.getFileSystem(ZipFileSystemProvider.java:169)
at jdk.zipfs/jdk.nio.zipfs.ZipFileSystemProvider.getPath(ZipFileSystemProvider.java:155)
at java.base/java.nio.file.Path.of(Path.java:208)
at java.base/java.nio.file.Paths.get(Paths.java:97)
at com.mkyong.io.utils.FileResourcesUtils.getAllFilesFromResource(FileResourcesUtils.java:128)
at com.mkyong.io.utils.FileResourcesUtils.main(FileResourcesUtils.java:35)
5. Get all files from a resource folder. (JAR version)
5.1 This example shows how to Files.walk
a folder inside a JAR file via FileSystems
and URI jar:file:xxx.jar
.
The idea is:
- File walks the folder inside a JAR file using
FileSystems
, and get all the filename, seegetPathsFromResourceJAR()
- Loop all the filename, access and print each file like example 2.1, see
getFileFromResourceAsStream()
.
package com.mkyong.io.utils;
import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
public class FileResourcesUtils {
public static void main(String[] args) throws IOException {
FileResourcesUtils app = new FileResourcesUtils();
// Sample 3 - read all files from a resources folder (JAR version)
try {
// get paths from src/main/resources/json
List<Path> result = app.getPathsFromResourceJAR("json");
for (Path path : result) {
System.out.println("Path : " + path);
String filePathInJAR = path.toString();
// Windows will returns /json/file1.json, cut the first /
// the correct path should be json/file1.json
if (filePathInJAR.startsWith("/")) {
filePathInJAR = filePathInJAR.substring(1, filePathInJAR.length());
}
System.out.println("filePathInJAR : " + filePathInJAR);
// read a file from resource folder
InputStream is = app.getFileFromResourceAsStream(filePathInJAR);
printInputStream(is);
}
} catch (URISyntaxException | IOException e) {
e.printStackTrace();
}
}
// get a file from the resources folder
// works everywhere, IDEA, unit test and JAR file.
private InputStream getFileFromResourceAsStream(String fileName) {
// The class loader that loaded the class
ClassLoader classLoader = getClass().getClassLoader();
InputStream inputStream = classLoader.getResourceAsStream(fileName);
// the stream holding the file content
if (inputStream == null) {
throw new IllegalArgumentException("file not found! " + fileName);
} else {
return inputStream;
}
}
// Get all paths from a folder that inside the JAR file
private List<Path> getPathsFromResourceJAR(String folder)
throws URISyntaxException, IOException {
List<Path> result;
// get path of the current running JAR
String jarPath = getClass().getProtectionDomain()
.getCodeSource()
.getLocation()
.toURI()
.getPath();
System.out.println("JAR Path :" + jarPath);
// file walks JAR
URI uri = URI.create("jar:file:" + jarPath);
try (FileSystem fs = FileSystems.newFileSystem(uri, Collections.emptyMap())) {
result = Files.walk(fs.getPath(folder))
.filter(Files::isRegularFile)
.collect(Collectors.toList());
}
return result;
}
// print input stream
private static void printInputStream(InputStream is) {
try (InputStreamReader streamReader = new InputStreamReader(is, StandardCharsets.UTF_8);
BufferedReader reader = new BufferedReader(streamReader)) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Output
$ java -jar target/java-io.jar
JAR Path :/C:/Users/mkyong/projects/core-java/java-io/target/java-io.jar
Path : /json/file2.json
filePathInJAR : json/file2.json
{
"name": "jack",
"age": 40
}
Path : /json/file1.json
filePathInJAR : json/file1.json
{
"name": "mkyong",
"age": 38
}
Path : /json/sub/subfile1.json
filePathInJAR : json/sub/subfile1.json
{
"name": "sub",
"age": 99
}
Download Source Code
$ git clone https://github.com/mkyong/core-java
$ cd java-io
How about reading al files under a resources directory like this?
src/main/resources
+ file1.txt
+ file2.txt
…
+ file9.txt
We updated the article, see example 4 and 5. Files.walk is your best friend.
And still, examples 4 and 5 shows how to access files in subfolder of resource folder, but not in resource folder itself.
Hi mkyong.This work fine ide but not work jar?
Can you help we ?
We updated the example to access the files inside the JAR file, the answer is
getResourceAsStream
.The
getResource
is not working in JAR file.The
getResourceAsStream
works everywhere.ClassLoader classLoader = ClassLoader.getSystemClassLoader();
InputStream inputStream = classLoader.getResourceAsStream(“fileName”);
StringWriter writer = new StringWriter();
IOUtils.copy(inputStream, writer);
query = writer.toString();
i am added Apache commons in mvn pom.xml then what is the query means
^ Thanks a lot man!
There is also one that I like the most:
File file = ResourceUtils.getFile(“classpath:file/test.txt”)
String txt= FileUtils.readFileToString(file);
ResourceUtils are in spring and FileUtils are in commons io.
OMG, many thanks for this ^^
Thanks for sharing this – ResourceUtils
Example 5 does not work on macOS.
I need to read a collection of json files from src/main/resources/specifications directory within the Jar context (they are classes/specificaitons within the Jar)
Getting java.lang.IllegalArgumentException: URI is not hierarchical when attempting to do this using the code in example 5.
The below code is the culprit as it is returning null. Omitting the .toURI().getPath() does return a URI but it has ! characters scattered throughout.
String jarPath = getClass().getProtectionDomain()
.getCodeSource()
.getLocation()
.toURI()
.getPath();
These your solutions doesn’t work on eclipse !
I’m working on an app which uses a 3rd party library with an API expecting a
java.io.File
.The data to be passed “as a file” I could create dynamically or get from a resource.
I could get the resource as a File with the class loader
getResource
method. But you already made the point: that will not work with a Jar.The only solution so far (independently if I create the data on the fly or get it (as Stream) from a resource) is to store that data in a temporal file and give it to the API.
Is there a way to avoid the temporal file? Can we make a File object for something in memory?
InputStream fis = getClass().getClassLoader().getResourceAsStream(“fileName.json”);
JSONParser jsonParser = new JSONParser();
JSONObject jsonObject = (JSONObject) jsonParser.parse(
new InputStreamReader(fis, “UTF-8”));
Excellent!!
What if you get NullPointer when retrieving the resource? Resource is in src/main/resources.
For Maven, check the
target/classes
folder, is the resource file there?use .toResource() instead of getFile to change the URL to a string. This worked for me
Null means it didn’t find it, is it there? check your path?
If I have this code
InputStream in = this.getClass().getClassLoader().getResourceAsStream(somefile.txt);
And my application is deployed on tomcat8. Where should I put somefile.txt so it can be found by the app?
new File(classLoader.getResource(fileName).getFile());This won’t work with files if they have whitespaces or special characters (e.g. #) in their paths. Rather use
new File(classLoader.getResource(fileName).toURI());
Thanks, we updated the example with
toURI()
thankq
toURI() does not work in jar and gives a error: URI is not hierarchical
Thanks to MyKong and you I got it working!
Thank You!
I would like to know how to know how to extract files which are in a folder which itself is in another folder.
I want to read all files from the resource folder and add them to a map, can you plz help ?
How do I use example 2 to read/map data from a file to a Java object (POJO)?
Does this code work with Java 11 or later versions?
Yes
Getting null pointer exception as the a=value of Jarpath. I have to get all the resources placed under the resources/json.
very good, thanks a lot 🙂
o lot of words for a simple thing. it is not good for java
.may do you have a simpler way?
Amazing! Thanks!!
Please advise:
Is it possible for you to read from any JAR, even a JAR that you only reference in your pom.xml dependencies?
iow: If you’re coding in ProjectA.war but in your pom.xml you reference ProjectB.jar… can you read a known filename(src/main/resources/this.xml) from ProjectB.jar, and output its content or use it as a file path in your ProjectA.war ?
Hello and thanks in advance. What about of reading not txt files? I.e. an .odf file?
Many thanks, you save me from a major headache which was plaguing me.
How to read a file not in Resources folder
It depends on how you copy the file to your classpath. Usually, files in
resources
will copy to the root of thetarget/classes
Thanks!
I have put lot of efforts but finally i found solution from here great…………..
Why do you use forward slash as a file separator. Why not File.separator, which fails on Windows. And why does File.separator fail on Windows? What should I use (but not hardcoded)?
Thanks for sharing
AntuanSoft:
To use in a static context you have to use:
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
ClassLoader classLoader = Hello.class.getClassLoader() also works.
how do you write files to resources folder (on eclipse env)?
Hi,
It work :)!
I have a question: How do to return an array with 4 file lines, chosen randomly from file?
Thanks . Worked like a charm !