[Java Foundation] deep jar Package: Reading a resource file from a jar package

Source: Internet
Author: User
Tags file url

Reprint: Http://hxraid.iteye.com/blog/483115?page=3#comments

We often read some resource files in the code (compared to slices, music, text, etc.). These simple processes are of course not problematic when running alone. However, if we make the code into a jar package, even if the resource files are packaged together, these things will not be found. Take a look at the following code:

//Source code 1: PackageEdu.hxraid;ImportJava.io.*; Public classResource { Public  voidGetResource ()throwsioexception{File File=NewFile ("Bin/resource/res.txt"); BufferedReader BR=NewBufferedReader (Newfilereader (file)); String s="";  while((S=br.readline ())! =NULL) System.out.println (s); }}    

This code is written in the eclipse-built Java project, where the directory is: (where the resource file Res.txt is placed in the bin directory to make a jar package)
1, src/
Src/edu/hxraid/resource.java
2, bin/
Bin/resource/res.txt
Bin/edu/hxraid/resource.class

Obviously running source code 1 is able to find the resource file res.txt. But when we make the whole project into a jar package (Resourcejar.jar), the directory inside the jar is:
Edu/hxraid/resource.class
Resource/res.txt

In this case, the Resource.class bytecode in the jar package: LDC <string "Bin/resource/res.txt" > [20] will not be able to navigate to the Res.txt location in the jar package. Even if the bin/directory is removed: LDC <string "Resource/res.txt" > [20] still cannot locate the Res.txt in the jar package.

this is mainly because the jar package is a separate file rather than a folder, and it is absolutely impossible to locate res.txt through the "file:/e:/.../resourcejar.jar/resource/res.txt" file URL. So even with a relative path, you can't locate the TXT file within the jar file (the reader may have some confusing explanations for this reason, and we'll elaborate on the results of a run of code below).

Then the resource into the jar package, no matter what path Resourcejar.jar in the system, the bytecode program in the jar package can find the resources in the package. Is this going to be a fantasy?

Of course not, we can use the class loader (ClassLoader) to do this:

(1) ClassLoader is an abstract class of Class loaders. It can dynamically get the run information of the load class at run time. It can be said that when we call the resource class in Resourcejar.jar, the JVM loads into the resource class and records the resource runtime information (including the path information for the jar package where resource is located). The methods in the ClassLoader class can help us to obtain this information dynamically:
Public URL getresource (String name)
Finds a resource with the given name. A resource is some data (images, sounds, text, and so on) that can be accessed through class code in a code-base-independent manner. and returns the URL object for the resource.
Public InputStream getResourceAsStream (String name);
Returns the input stream that reads the specified resource. This method is important to get the contents of the files in the jar package directly.

(2) ClassLoader is abstract, it is impossible to instantiate an object, it is more impossible to call the above two methods through ClassLoader. So when we actually write the code, it's through the GetResource () and getResourceAsStream () methods in the class classes, and these two methods delegate the GetResource () in ClassLoader and getResourceAsStream () method . Well, now we re-write a resource code to see what the above puzzling words mean:

//Source code 2: PackageEdu.hxraid;ImportJava.io.*;ImportJava.net.URL; Public classResource { Public  voidGetResource ()throwsioexception{//finds the URL of the specified resource, where Res.txt still starts in the bin directoryURL fileurl= This. GetClass (). GetResource ("/resource/res.txt");    System.out.println (Fileurl.getfile ()); }     Public Static voidMain (string[] args)throwsIOException {Resource res=NewResource ();    Res.getresource (); }}

Run this source code result:/e:/code_factory/wanwan/bin/resource/res.txt (.. /code_factory/wanwan/. is the path where Java project resides)

We package this code into Resourcejar.jar and place the Resourcejar.jar under other paths (such as C:\ResourceJar.jar). Then create another Java project and import Resourcejar.jar to write a test code that calls the resource class in the JAR package:

Import java.io.IOException; Import Edu.hxraid.Resource;  Public class TEST {    publicstaticvoidthrows  IOException {        Resource res=new  Resource ();        Res.getresource ();    }}

The result of this operation is: File:/c:/resourcejar.jar!/resource/res.txt

We managed to get the res.txt position dynamically at run time. However, the question comes, can you get the Res.txt file using the code below?
File F=new file ("C:/resourcejar.jar!/resource/res.txt");
Of course not, because ".../resourcejar.jar!/resource/..." is not the format of the file resource Locator (the resource in the jar has its own special URL form: jar:<url>!/{entry} ). Therefore, if the class source code in the jar package is in the form of file F=new files (relative path), it is not possible to locate the document resource. This is why when the source code 1 is packaged into a jar file, it is reported that the FileNotFoundException is the crux of the call to the jar package.

(3) We can not use the normal operation of the file method to read Resourcejar.jar in the resource file Res.txt, but it is available through the class getResourceAsStream () method to obtain , This approach is how to read the resource files in the jar, which is transparent to us. We rewrite the Resource.java into:

//Source Code 3: PackageEdu.hxraid;ImportJava.io.*; Public classResource { Public voidGetResource ()throwsioexception{//returns the input stream that reads the specified resourceInputStream is= This. GetClass (). getResourceAsStream ("/resource/res.txt"); BufferedReader BR=NewBufferedReader (NewInputStreamReader (IS)); String s="";  while((S=br.readline ())! =NULL) System.out.println (s); }}

We will edu/hxraid/resource.class and resource files in the/bin directory under Java engineering resource/ Res.txt packaged into the Resourcejar.jar, regardless of the jar package in any directory of the system, call the resource class in the jar package can obtain the Res.txt resources in the jar package, no longer cannot find the Res.txt file.

[Java Foundation] deep jar Package: Reading a resource file from a jar package

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.