Accessing a Resource in Java
A resource is data(audio, vedio, image, text etc.) that a program needs to access. Before accessing a resource by a Java program, the resorce is located on the underlying file system. Now, locating a resource on file system inside your project might be tricky for you.
There are following ways to locate a resource on file system from a Java Application-
a) Location dependent
b) Location Independent
A resource can be located on file-system by specifying a relative url or an absolute url for resource.
For the eclipse project structure shown in picture, the data files can be accessed from ResourceReader.java as below-
File file1 = new File(“Data1.txt”);
File file2 = new File(“resource/Data2.txt”);
File file3 = new File(“data/com/Data3.txt”);
Apart from this, you have got the option to specify an absolute path of the resource.
File file1 = new File(“C://………../Data1.txt”);
While accessing the resources using the location dependent ways, you are not supposed to change the project folder structure later on because that will lead to change each and every piece of Java code which is involved in accessing these resources.
Well, the Java code change because of resource location change can be avoided by specifying base location as environment variable. For exmaple – we can have an environment varibale as RESOURCE_BASE whose value can be set as inside configurations and the variable can be used further inside your Java code to form the complete path for a resource.
String base = System.getProperty(“RESOURCE_BASE”, “”);
File file = new File(base + “/data/com/Data3.txt”);
The methods from Class and ClassLoader classes enable you to access resources independent of their location. Both classes provides similar methods to read system resources and non-system resources for exmaple: getResource and getSystemResource.
Tip :- A system resource is a resource that is either built-in to the system, or kept by the host implementation in, for example, a local file system.)
Using methods from java.lang.ClassLoader
For a System Resource, the ClassLoader methods search each directory, ZIP file, or JAR file entry in the CLASSPATH for the resource file, and, if found, returns either an InputStream, or the resource name. If not found, the methods return null. A resource may be found in a different entry in the CLASSPATH than the location where the class file was loaded.
For a Non-System Resource, the implementation of getResource on a class loader depends on the details of the ClassLoader class. Generally,all class loaders first tries to locate the resource as a system resource; if not found, the behavior is dependent on the ClassLoader class.
ClassLoader class exposes two sets of methods – one set returns URL of the accesses resource while other resturns InputStream.
Data3.txt can be accessed from ResourceReader.java as–
URL url = ResourceReader.class.getClassLoader().getResource(“com/Data3.txt”);
Here the value of url will be the absolute path of file Data3.txt on file system. Note – the file Data3.txt is on classpath. Data2.txt is not available on classpath and hence cant be accessed using getResource mehod.
Data3.txt can be read as InputStream as below-
InputStream file = ResourceReader.class.getClassLoader().getResourceAsStream(“com/Data3.txt”);
Using methods from java.lang.Class
The method getResource() returns a URL for the resource. The URL (and its representation) is specific to the implementation and the JVM (that is, the URL obtained in one runtime instance may not work in another). Its protocol is usually specific to the ClassLoader loading the resource. If the resource does not exist or is not visible due to security considerations, the methods return null.
If the client code wants to read the contents of the resource as an InputStream, it can apply the openStream() method on the URL. This is common enough to justify adding getResourceAsStream() to Class and ClassLoader. getResourceAsStream() the same as calling getResource().openStream(), except that getResourceAsStream() catches IO exceptions returns a null InputStream.
Client code code can also request the contents of the resource as an object by applying the java.net.URL.getContent() method on the URL. This is useful when the resource contains the data for an image, for instance. In the case of an image, the result is an awt.image.ImageProducer object, not an Image object.
The getResource and getResourceAsStream methods find a resource with a given name. They return null if they do not find a resource with the specified name. The rules for searching for resources associated with a given class are implemented by the class’s ClassLoader. The Class methods delegate to ClassLoader methods, after applying a naming convention: if the resource name starts with “/”, it is used as is. Otherwise, the name of the package is prepended, after converting all periods (.) to slashes (/).
Important:- Observe the difference between behaviour of getResource() method from Class class and ClassLoader class. The method from Class class resolves the resource name as explained above and finally delegates it to ClassLoader.getResource().
Author – Yogendra sharma (YES)