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 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 into the root'/target/app-name'
folder. After the deployment in an application server, thewar
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 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.
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 !!
Leave a Reply