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 roottarget/classes
folder.
In this case, the file location is inside a zipped archive likejar-filename.jar/!filename.txt
. We should directly read this file asInputStream
. - When packaging the application as war file, the file present in the
resources
folder are copied in the roottarget/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 usingFile
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.
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 !!
Thank you so much for sharing. This helps me a lot
Works either from filesystem and JAR:
Solve my problem, thanks!
will this procedure work for a .xlsx file too?
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
Also see this: https://docs.oracle.com/javase/7/docs/technotes/guides/io/fsp/zipfilesystemprovider.html
Thanks for sharing. Much appreciated !!
Thanks it works !!!
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”
Thanks it works
Vikas