Reading 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 is “src/main/resources“.

  • When packaging the application as jar file, the file present in the resources folder are copied in 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 in the root target/app-name folder.
    After the deployment, 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 are reading two files present 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. 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.

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.

package com.howtodoinjava.io;

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

3. Resources Packaged as .war File

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

4. Using ResourceUtils in Spring Application

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

Was this post helpful?

Join 7000+ Awesome Developers

Get the latest updates from industry, awesome resources, blog updates and much more.

* We do not spam !!

9 thoughts on “Reading a File from Resources Directory”

  1. Works either from filesystem and JAR:

    	public static void main(String[] args) throws IOException {
    
    		String resourceFile = &quot;resource/test_resource.txt&quot;;
    
    		InputStream resourceStream = ClassLoader.getSystemClassLoader().getResourceAsStream(resourceFile);
    
    		if (resourceStream != null) {
    			BufferedReader resReader = new BufferedReader(new InputStreamReader(resourceStream));
    			System.out.println(resReader.lines().collect(Collectors.joining()));
    		}
    	}
    
    Reply
  2. The class loader method works when I run it in IDE, but not when the application is packaged as a jar file. I had to use a ZIP file system to load it from a jar file e.g

    	private byte[] loadData() throws Exception {
    
    		String relativePath = &quot;META-INF/somebinaryfile.bmp&quot;;
    		URI resource = getClass().getClassLoader().getResource(relativePath).toURI();
    
    		byte[] data = null;
    		try(FileSystem jarFileSystem = FileSystems.getFileSystem(resource)) {
    			data = readDataFromFile(relativePath, jarFileSystem);
    		} catch (FileSystemNotFoundException e) {
    			 Map&lt;String, String&gt; env = new HashMap&lt;String, String&gt;();
    			 env.put(&quot;create&quot;, &quot;true&quot;);
    			try (FileSystem jarFileSystem = FileSystems.newFileSystem(resource, env)) {
    				data = readDataFromFile(relativePath, jarFileSystem);
    			}
    		}
    		return data;
    	}
    
    	private byte[] readDataFromFile(String fileName, FileSystem jarFileSystem) throws IOException {
    
    		Path path = jarFileSystem.getPath(fileName);
    		byte[] data = Files.readAllBytes(path);
    		return data;
    	}
    

    Also see this: https://docs.oracle.com/javase/7/docs/technotes/guides/io/fsp/zipfilesystemprovider.html

    Reply
  3. not working for me, I’m getting this error “Exception in thread “main” java.lang.NullPointerException” and if I try using the filename without folder the error is “\target\classes\sample.txt”

    Reply

Leave a Comment

HowToDoInJava

A blog about Java and related technologies, the best practices, algorithms, and interview questions.