Java IO Tutorial

Java – Read a file from resources folder

Java 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.

project structure

src/main/resources/database.properties

datasource.url=jdbc:mysql://localhost/mkyong?useSSL=false
datasource.username=root
datasource.password=password
datasource.driver-class-name=com.mysql.jdbc.Driver
src/main/resources/json/file1.json

{
  "name": "mkyong",
  "age": 38
}
src/main/resources/json/file2.json

{
  "name": "jack",
  "age": 40
}
src/main/resources/json/sub/subfile1.json

{
  "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.

copy resources to classes

1.3 Below is a JAR file structure. Usually, the files in the resources folder will copy to the root of the classpath.

Terminal

$ 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.
FileResourcesUtils.java

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

Terminal

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.

Terminal

$ 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.

Terminal

$ 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.

pom.xml

  <!-- 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.

resources for unit tests

src/test/resources/json/file1.json

{
  "name": "unit test",
  "age": 38
}
src/test/resources/database.properties

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.

FileResourcesTest.java

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

Terminal

{
  "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:

FileResourcesUtils.java

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

Terminal

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.

Terminal

$ 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, see getPathsFromResourceJAR()
  • Loop all the filename, access and print each file like example 2.1, see getFileFromResourceAsStream().
FileResourcesUtils.java

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

Terminal

$ 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

References

About Author

author image
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

Subscribe
Notify of
58 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
Jack Nolddor
7 years ago

How about reading al files under a resources directory like this?

src/main/resources
+ file1.txt
+ file2.txt

+ file9.txt

Alex
3 years ago
Reply to  mkyong

And still, examples 4 and 5 shows how to access files in subfolder of resource folder, but not in resource folder itself.

alikemal ocalan
8 years ago

Hi mkyong.This work fine ide but not work jar?
Can you help we ?

name
5 years ago

ClassLoader classLoader = ClassLoader.getSystemClassLoader();
InputStream inputStream = classLoader.getResourceAsStream(“fileName”);
StringWriter writer = new StringWriter();
IOUtils.copy(inputStream, writer);
query = writer.toString();

karthi chandran
3 years ago
Reply to  name

i am added Apache commons in mvn pom.xml then what is the query means

robben09
5 years ago
Reply to  name

^ Thanks a lot man!

Grzegorz Solecki
9 years ago

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.

Khue Nguyen
7 years ago

OMG, many thanks for this ^^

mkyong
9 years ago

Thanks for sharing this – ResourceUtils

Charlie
1 year ago

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

vinh
2 years ago

These your solutions doesn’t work on eclipse !

Jesús Gómez
2 years ago

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?

Katy xinh dep
4 years ago

InputStream fis = getClass().getClassLoader().getResourceAsStream(“fileName.json”);
JSONParser jsonParser = new JSONParser();
JSONObject jsonObject = (JSONObject) jsonParser.parse(
new InputStreamReader(fis, “UTF-8”));

daniel
6 years ago

Excellent!!

Luke
6 years ago

What if you get NullPointer when retrieving the resource? Resource is in src/main/resources.

Marcelino Puente-Perez
4 years ago
Reply to  Luke

use .toResource() instead of getFile to change the URL to a string. This worked for me

ROGER DELOY PACK
4 years ago
Reply to  Luke

Null means it didn’t find it, is it there? check your path?

Moreno Garcia
6 years ago

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?

Karl Huebner
8 years ago

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

vinay
3 years ago
Reply to  Karl Huebner

thankq

ANKUR
5 years ago
Reply to  Karl Huebner

toURI() does not work in jar and gives a error: URI is not hierarchical

Mohammed Salman
6 years ago
Reply to  Karl Huebner

Thanks to MyKong and you I got it working!

Brandon Dudek
6 years ago
Reply to  Karl Huebner

Thank You!

Nirupama
8 years ago

I would like to know how to know how to extract files which are in a folder which itself is in another folder.

Girja
2 years ago

I want to read all files from the resource folder and add them to a map, can you plz help ?

Kyle
2 years ago

How do I use example 2 to read/map data from a file to a Java object (POJO)?

mohamed
2 years ago

Does this code work with Java 11 or later versions?

Deepti
3 years ago

Getting null pointer exception as the a=value of Jarpath. I have to get all the resources placed under the resources/json.

jop
3 years ago

very good, thanks a lot 🙂

David
3 years ago

o lot of words for a simple thing. it is not good for java
.may do you have a simpler way?

David
3 years ago
Reply to  David

// to use jackson lib in maven repo
try (InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("yourFile.json")) {
    ObjectMapper mapper = new ObjectMapper();
    return mapper.readValue(in, YourModel.class);
} catch (Exception e) {
    throw new RuntimeException(e);
}
Last edited 3 years ago by David
Watchuta
3 years ago

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 ?

Jose Requeijo Figueiras
4 years ago

Hello and thanks in advance. What about of reading not txt files? I.e. an .odf file?

Andreas Müller
4 years ago

Many thanks, you save me from a major headache which was plaguing me.

Mubeen
5 years ago

How to read a file not in Resources folder

Mohammed Salman
6 years ago

Thanks!

Krishna
6 years ago

I have put lot of efforts but finally i found solution from here great…………..

Jan Khonski
7 years ago

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)?

Carol
8 years ago

Thanks for sharing

AntuanSfot
8 years ago

AntuanSoft:

To use in a static context you have to use:

ClassLoader classLoader = ClassLoader.getSystemClassLoader();

Anderson Gomes
7 years ago
Reply to  AntuanSfot

ClassLoader classLoader = Hello.class.getClassLoader() also works.

Neeraj Lal
8 years ago

how do you write files to resources folder (on eclipse env)?

nosperov
9 years ago

Hi,
It work :)!
I have a question: How do to return an array with 4 file lines, chosen randomly from file?

Anirban Kundu
9 years ago

Thanks . Worked like a charm !