Read a File from Resources Directory

Learn to read a file from the resources folder in a Java application. We will learn to read the file present inside the jar file, and outside the Jar file as well. A file outside the jar file may be present as a war file or an Eclipse project in the development environment.

1. Packaging a File into resources Folder

The resources folder belongs to the Maven project structure where we place the configuration and data files related to the application. The location of the folder can be “src/main/resources” and “src/test/resources“.

  • When packaging the application as jar file, the file present in the '/resources' folder are copied into the root 'target/classes' folder. In this case, the file location is inside a zipped archive like jar-filename.jar/!filename.txt. We should directly read this file as InputStream.
  • When packaging the application as war file, the file present in the '/resources' folder are copied into the root '/target/app-name' folder. After the deployment in an application server, the war files are extracted in a server work directory. So, in this case, we are reading the file outside a zipped archive so we can refer to the file using a relative path. We can refer to this file using File instance and can use any suitable method to read the file content.

In the given examples, we read two files in the /resources folder. The first file /demo.txt is at the root of /resources folder. The second file /data/demo.txt folder is inside a nested folder /data in the resources folder.

The file locations in the resources folder

2. Resources Packaged as .jar File

2.1. Using ClassLoader.getResourceAsStream()

Use the getResourceAsStream() method to get the InputStream when reading a file from inside a jar file. Always use this method on the ClassLoader instance.

This code works on the development environment also.

private InputStream getFileAsIOStream(final String fileName) 
{
    InputStream ioStream = this.getClass()
        .getClassLoader()
        .getResourceAsStream(fileName);
    
    if (ioStream == null) {
        throw new IllegalArgumentException(fileName + " is not found");
    }
    return ioStream;
}

2.2. Complete Example

Once we have the InputStream reference, we can use it to read the file content or pass it to any resource handler class.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class ReadFileFromResourcesUsingGetResourceAsStream 
{
    public static void main(final String[] args) throws IOException 
    {
        //Creating instance to avoid static member methods
        ReadFileFromResourcesUsingGetResourceAsStream instance 
            = new ReadFileFromResourcesUsingGetResourceAsStream();

        InputStream is = instance.getFileAsIOStream("demo.txt");
        instance.printFileContent(is);
        
        is = instance.getFileAsIOStream("data/demo.txt");
        instance.printFileContent(is);
    }

    private InputStream getFileAsIOStream(final String fileName) 
    {
        InputStream ioStream = this.getClass()
            .getClassLoader()
            .getResourceAsStream(fileName);
        
        if (ioStream == null) {
            throw new IllegalArgumentException(fileName + " is not found");
        }
        return ioStream;
    }

    private void printFileContent(InputStream is) throws IOException 
    {
        try (InputStreamReader isr = new InputStreamReader(is); 
                BufferedReader br = new BufferedReader(isr);) 
        {
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
            is.close();
        }
    }
}

2.3. How to test the code

To test the above code, package the application as jar file using 'mvn clean package' command. Also, provide the 'mainClass' attribute to maven-jar-plugin and set its value to the class which has main() method and the test code.

<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-jar-plugin</artifactId>
	<version>3.2.0</version>
	<configuration>
		<archive>
			<manifest>
				<mainClass>com.howtodoinjava.io.ReadFileFromResourcesUsingGetResourceAsStream</mainClass>
			</manifest>
		</archive>
	</configuration>
</plugin>

Now, run the main() method from the console.

mvn clean package
java -jar target\app-build-name.jar

Content from demo.txt
Content from data/demo.txt

3. Resources Packaged as .war File

3.1. Using ClassLoader.getResource()

Use the getResource() method to get the File instance when reading a file from inside a war file. I suggest using this method on the ClassLoader instance.

private File getResourceFile(final String fileName) 
{
    URL url = this.getClass()
        .getClassLoader()
        .getResource(fileName);
    
    if(url == null) {
        throw new IllegalArgumentException(fileName + " is not found 1");
    }
    
    File file = new File(url.getFile());
    
    return file;
}

3.2. Complete Example

Now use the File reference to read the file content.

package com.howtodoinjava.io;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.file.Files;

public class ReadFileFromResourcesUsingGetResource {
    public static void main(final String[] args) throws IOException 
    {
        //Creating instance to avoid static member methods
        ReadFileFromResourcesUsingGetResource instance 
            = new ReadFileFromResourcesUsingGetResource();

        File file = instance.getResourceFile("demo.txt");
        instance.printFileContent(file);
        
        file = instance.getResourceFile("data/demo.txt");
        instance.printFileContent(file);
    }

    private File getResourceFile(final String fileName) 
    {
        URL url = this.getClass()
            .getClassLoader()
            .getResource(fileName);
        
        if(url == null) {
            throw new IllegalArgumentException(fileName + " is not found 1");
        }
        
        File file = new File(url.getFile());
        
        return file;
    }

    private void printFileContent(File file) throws IOException 
    {
        String content = new String(Files.readAllBytes(file.toPath()));
        System.out.println(content);
    }
    
    private void printFileContent(InputStream is) throws IOException 
    {
        try (InputStreamReader isr = new InputStreamReader(is); 
                BufferedReader br = new BufferedReader(isr);) 
        {
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
            is.close();
        }
    }
}

3.3. How to test the code

To test the above code, package the application as a war file using mvn clean package command. Use the maven-resources-plugin plugin to copy the files from the resources folder to the root of the war file archive.

<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-war-plugin</artifactId>
	<version>3.2.0</version>
	<configuration>
		<failOnMissingWebXml>false</failOnMissingWebXml>
	</configuration>
</plugin>
<plugin>
	<artifactId>maven-resources-plugin</artifactId>
	<version>2.4.3</version>
	<executions>
		<execution>
			<id>copy-resources</id>
			<phase>process-resources</phase>
			<goals>
				<goal>copy-resources</goal>
			</goals>
			<configuration>
				<overwrite>true</overwrite>
				<outputDirectory>${project.build.directory}/${project.artifactId}-${project.version}/</outputDirectory>
				<resources>
					<resource>
						<directory>${project.basedir}/src/main/resources</directory>
					</resource>
				</resources>
			</configuration>
		</execution>
	</executions>
</plugin>

Now, run the main method from the console. Do not forget to add the classes to the classpath.

mvn clean package
java -classpath "classes/." com.howtodoinjava.io.ReadFileFromResourcesUsingGetResource

Content from demo.txt
Content from data/demo.txt

4. Using ResourceUtils in Spring /Boot Applications

If the application is a Spring WebMVC or Spring Boot application then we may take advantage of org.springframework.util.ResourceUtils class.

File file = ResourceUtils.getFile("classpath:demo.txt")

//File is found
System.out.println("File Found : " + file.exists());

//Read File Content
String content = new String(Files.readAllBytes(file.toPath()));
System.out.println(content);

Happy Learning !!

Comments

Subscribe
Notify of
guest
3 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.