Many a times, we are often required to read a file into our application. That file can be located anywhere in the system or network. To handle such file accessing tasks, Spring provides an interface called as "Resource" contained in the package org.springframework.core.io. To stream in the file, this interface has a method called as getInputStream() and many other methods that can come handy to get the file information. So now lets see how we can use this functionality in our code.

The following code will read a file named sample.txt located in the src folder in the current working directory using class FileSystemResource

		InputStream inputStream = null;
		Resource resource = null;
		try {
			resource = new FileSystemResource("src/sample.txt");
			inputStream = resource.getInputStream();
			Scanner scanner = new Scanner(inputStream);
			while (scanner.hasNext()) {
				System.out.println(scanner.nextLine());
			}
		} finally {
			if (inputStream != null) {
				inputStream.close();
			}
		}

For the files which you usually access using the url protocol like http://, ftp://, file:// etc, we have UrlResource. The following code will read a file named sample.txt present in C drive and that can be accessed from your browser using file:// protocol.

InputStream inputStream = null;
Resource resource = null;
try {
resource = new UrlResource("file:///C:/sample.txt");
	inputStream = resource.getInputStream();
	Scanner scanner0 = new Scanner(inputStream);
	while (scanner0.hasNext()) {
		System.out.println(scanner0.nextLine());
	}
} finally {
	if (inputStream != null) {
		inputStream.close();
	}
}

For the resources that are present on your classpath, you can use ClassPathResource. The following code will read in a file named sample.txt present in the classpath.

InputStream inputStream = null;
Resource resource = null;
try {
resource = new ClassPathResource("sample.txt");
	inputStream = resource.getInputStream();
	Scanner scanner0 = new Scanner(inputStream);
	while (scanner0.hasNext()) {
		System.out.println(scanner0.nextLine());
	}
} finally {
	if (inputStream != null) {
		inputStream.close();
	}
}

Injecting Resources

Moving forward, lets say you need to have a reference of some resource which you are going to use in your code. To do this, we actually have two ways, which are mentioned as below:

  • Resource Injection: Here we inject resources like the usual Spring Injection. This way is used for loading static resources i.e. when we know the resource which is required beforehand.
  • Using ResourceLoader: Here we use ResourceLoader interface to help us a resource we require. This way is used for loadind dynamic resources i.e which will be loaded based on some business logic.

Resource Injection: for static resources

package resourceinjection;
import org.springframework.core.io.Resource;

public class ResourceInjection {
private Resource textFile;

public void setTextFile(Resource textFile) {
  this.textFile = textFile;
}
public Resource getTextFile() {
  return textFile;
}
}

In the above class, we have created a property of type Resource. And in the below context xml file(highlighted line no 7) we have injected this property with the path of the file we want spring to provide us with.

resourceContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
	<bean id="resourceInjection" class="springresources.ResourceInjection">
		<property name="textFile" value="springresources/sample.txt"></property>
	</bean>
</beans>

SpringResourceTest.java

package resourceinjection;
import java.io.InputStream;
import java.util.Scanner;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.Resource;

public class SpringResourceTest {
	public static void main(String[] args) throws Exception {
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
				"resourceinjection/resourceContext.xml");
		InputStream inputStream = null;
		Scanner scanner = null;
		try {
			
			ResourceInjection resourceInjection = applicationContext.getBean(
					"resourceInjection", ResourceInjection.class);
			
			Resource springBeanInjectedResource = resourceInjection.getTextFile();
			inputStream = springBeanInjectedResource.getInputStream();
			scanner = new Scanner(inputStream);
			while (scanner.hasNext()) {
				System.out.println(scanner.nextLine());
			}
			
		} finally {
			if (inputStream != null) {
				inputStream.close();
			}
		}
	}
}

In the above test class, we get this bean in the usual way and when you get the textFile property from this bean (line no 19), you can successfully read the information from this resource object. Now let us see the second way i.e how to access dynamic resources.

ResourceLoader Injection: for dynamic resources

package resourceinjection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;

public class ResourceInjection {
	@Autowired
	private ResourceLoader resourceLoader;

	public Resource loadDynamicResource(){
		boolean someCondition=true;
		if(someCondition){
			return resourceLoader.getResource("resourceinjection/sample2.txt");
		}else{
			return resourceLoader.getResource("resourceinjection/sample.txt");
		}
	}
}

The above class has a property of type ResourceLoader. This ResourceLoader will be used to dynamically load a resource as seen in the above highlighted lines 13 and 15. To tell the spring about injecting value into this, we have used the @Autowired annotation. With annotations, we need not create setter methods for our properties. Only thing we have to do is to tell Spring framework that we are using the annotation, so in addition to the injecting values based on the property tags from the xml, it has to read class level annotations also. We do this by adding <context:annotation-config /> in the content xml file as seen below.

resourceContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
	http://www.springframework.org/schema/context 
	http://www.springframework.org/schema/context/spring-context-3.0.xsd">
	<context:annotation-config />
	<bean id="resourceInjection" class="resourceinjection.ResourceInjection">
	</bean>
</beans>
SpringResourceTest.java
package resourceinjection;

import java.io.InputStream;
import java.util.Scanner;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.Resource;

public class SpringResourceTest {
	public static void main(String[] args) throws Exception {

		ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
				"resourceinjection/resourceContext.xml");
		InputStream inputStream = null;
		Scanner scanner = null;
		try {
			ResourceInjection resourceInjection = applicationContext.getBean(
					"resourceInjection", ResourceInjection.class);
			Resource dynamicResourceViaResourceLoader = resourceInjection
					.loadDynamicResource();
			inputStream = dynamicResourceViaResourceLoader.getInputStream();
			scanner = new Scanner(inputStream);
			while (scanner.hasNext()) {
				System.out.println(scanner.nextLine());
			}
		} finally {
			if (inputStream != null) {
				inputStream.close();
			}
		}
	}
}

In our test class, we get this bean in the usual way and call its loadDynamicResource. This method internally uses the ResourceLoader to return a Resource dynamically.

Download Source