Read a File from Resources Folder in Java

This tutorial illustrates How to read a file from Classpath or Resources Folder in Java using File IO, NIO, and FileChannel.

Overview

All Maven and Gradle projects follow Maven’s standard directory structure (link), which helps segregate different types of source files in dedicated directories. Application-level configurations (like Properties and YAML) and other files reside in the resources directory.

  • src/main/resources – A place to keep Application level resources and files.
  • src/test/resources – A place to keep resources and files for the test purpose.

Java provides several ways to read the files from the resources directory. The following tutorial covers examples of reading files from ‘src/main/resources‘ or ‘src/test/resources‘ directory.

Using Plain Java – getResourceAsStream()

Java Class class provides the getResourceAsStream() method that can open an InputStream to a file in the classpath.

To read a file from the ‘src/main/resources‘ we need to provide a file path relative to this directly. When we invoke getResourceAsStream() in a unit test, it reads the file from ‘src/test/resources‘ directory.

InputStream inputStream = 
    this.getClass().getResourceAsStream("/file.txt");Code language: Java (java)

We can now use the InputStream instance to read the file’s contents.

try (
    InputStream is = this.getClass().getResourceAsStream("/file.txt");
    InputStreamReader isr = new InputStreamReader(is);
    BufferedReader br = new BufferedReader(isr);
    Stream<String> lines = br.lines();
) {
  lines.forEach(System.out::println);
}Code language: Java (java)

Firstly, we use the Class.getResourceAsStream() method to retrieve an InputStream to the intended file. Then we create an InputStreamReader instance to build a BufferedReader instance. The BufferedReader‘s lines() method provides a Java Stream of the lines from the file.

The lines() method of the BufferedReader is lazy. This means it reads lines if we consume the stream.

Note that we are using try-with-resources that automatically helps us close various File IO resources and streams.

Alternatively, we can use getResourceAsStream on the class loader.

InputStream inputStream = this.getClass()
    .getClassLoader()
    .getResourceAsStream("file.txt");Code language: Java (java)

The difference between the two is that using getResourceAsStream() on the Class instance is relative to the resources folder. Thus, we added a slash (/) to the path. On the other hand, getResourceAsStream() on the class loader instance takes an absolute path, which is why we have not added the slash (/).

Using FileReader

We can create a FileReader instance by providing the file’s path relative to the project root. We can then wrap the FileReader into a BufferedReader instance and use the BufferedReader to read the file in a Stream of lines.

Example of using the FileReader to read a file from the resources directory

try (
    FileReader fr = new FileReader("src/main/resources/file.txt");
    BufferedReader br = new BufferedReader(fr);
    Stream<String> lines = br.lines();
) {
  lines.forEach(System.out::println);
}Code language: Java (java)

Using Files.newBufferedReader()

Java NIO’s Files class provides a static method, newBufferedReader(), that we can use to build a BufferedReader instance. To do so, we must give the file’s path relative to the project root.

Example of using the newBufferedReader() method from Java NIO Files class to read a file from the resources directory.

try (
    BufferedReader br = Files.newBufferedReader(
        Paths.get("src/main/resources/file.txt"));
    Stream<String> lines = br.lines();
) {
  lines.forEach(System.out::println);
}Code language: Java (java)

Using Files.lines()

Alternatively, the more straightforward way is to use the Java NIO Files class’s lines() method. The lines() method accepts the file’s path relative to the project root directory. It returns a Java Stream of the lines from the file.

Example of using the lines() method of Java NIO Files to read a file from the “src/main/resources” or “src/test/resources” directory.

try (
    Stream<String> lines = Files.lines(path, StandardCharsets.UTF_8)
) {
  lines.forEach(System.out::println);
}Code language: Java (java)

Using DataInputStream

We can also combine the Java Class’s getResourceAsStream() method with an DataInputStream instance to read a file from the resources directory or classpath.

Example of using the DataInputStream to read a file from the resources folder.

try (
    InputStream is = this.getClass().getResourceAsStream("/file.txt");
    DataInputStream dis = new DataInputStream(is);
) {
  int numBytesRead;
  if ((numBytesRead = dis.available()) > 0) {
    byte[] bucket = new byte[numBytesRead];
    dis.read(bucket);
    System.out.println(new String(bucket));
  }
}Code language: Java (java)

Firstly, we used the getResourceAsStream() method to create an InputStream to the file from resources directory. Next, we wrapped the InputStream instance into a DataInputStream instance. The DataInputStream is useful for reading primitive java data types from a file.

Using FileChannel

Using FileChannel to read a file from the resources diretory is fastest of all the ways, especially when the file is large.

Example of using the FileChannel to read a file from “src/main/resources” or “src/test/resources” directory.

Path path = Path.of(this.getClass().getResource("/file.txt").toURI());
try (
    RandomAccessFile raf = new RandomAccessFile(path.toFile(), "r");
    FileChannel fc = raf.getChannel();
) {
  int bucketSize = 1024;
  ByteBuffer byteBuffer = ByteBuffer.allocate(bucketSize);
  fc.read(byteBuffer);
  byteBuffer.flip();
  System.out.println(new String(byteBuffer.array()));
}Code language: Java (java)

To obtain a FileChannel mapped to our file, we first create a RandomAccessFile instance. We can then use the FileChannel instance to read the file chunk by chunk.

Summary

In this detailed tutorial, we have learned different ways of reading a file from the resources directory (“src/main/resources” or “src/test/resources” folders) or classpath. We went through the examples of reading a files using the plain Java, Java NIO, and FileChannel.