Java reads the resource file from the jar package

Source: Internet
Author: User
Tags file url

(GO) Java reads the resource file from the jar package Blog Category:
    • Java

From: http://blog.csdn.net/b_h_l/article/details/7767829

There is no problem when reading some resource files in code (compared to slices, music, text, etc.) and running in the integrated Environment (ECLIPSE). However, when packaged into an executable jar package (package the resource files), these resource files cannot be found, as in the following code:
Java code

[Java]View Plaincopy
  1. Source Code 1:
  2. Package edu.hxraid;
  3. Import java.io.*;
  4. Public class Resource {
  5. public void GetResource () throws ioexception{
  6. File file=new file ("Bin/resource/res.txt");
  7. BufferedReader br=New BufferedReader (new FileReader (file));
  8. String s="";
  9. While ((S=br.readline ()) =null)
  10. System.out.println (s);
  11. }
  12. }

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:
Java code

[Java]View Plaincopy
  1. Source Code 2:
  2. Package edu.hxraid;
  3. Import java.io.*;
  4. Import Java.net.URL;
  5. Public class Resource {
  6. public void GetResource () throws ioexception{
  7. //Find the URL of the specified resource, where Res.txt still starts in the bin directory
  8. URL fileurl=This.getclass (). GetResource ("/resource/res.txt");
  9. System.out.println (Fileurl.getfile ());
  10. }
  11. public static void Main (string[] args) throws IOException {
  12. Resource res=New Resource ();
  13. Res.getresource ();
  14. }
  15. }

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:
Java code

[Java]View Plaincopy
  1. Import java.io.IOException;
  2. Import Edu.hxraid.Resource;
  3. Public class TEST {
  4. public static void Main (string[] args) throws IOException {
  5. Resource res=New Resource ();
  6. Res.getresource ();
  7. }
  8. }

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.
Note: We can get the ImageIcon object through new ImageIcon (class. Class.getResource ("Xx.gif")), but if you want to get the resource file stream in the jar file, the above method won't work.
(3) We can not use the normal operation of the file method to read the resource file Res.txt in Resourcejar.jar, but it is available through the class getResourceAsStream () method, this method is how to read the resource file in the jar, This is transparent to us. We rewrite the Resource.java into:
Java code

[Java]View Plaincopy
  1. Source Code 3:
  2. Package edu.hxraid;
  3. Import java.io.*;
  4. Public class Resource {
  5. public void GetResource () throws ioexception{
  6. //Returns the input stream that reads the specified resource
  7. InputStream is=This.getclass (). getResourceAsStream ("/resource/res.txt");
  8. //inputstream is= Current class. Class.getresourceasstream ("Xx.config");
  9. BufferedReader br=New BufferedReader (new InputStreamReader (IS));
  10. String s="";
  11. While ((S=br.readline ()) =null)
  12. System.out.println (s);
  13. }
  14. }

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.

(4) The above method only provides read the resource file from the JAR function, does not provide the overwrite jar in the resource file method,

The input stream (InputStream) and the output stream (outputstream) of the resource file in the jar are obtained through the URL, URLConnection, and not only can read the resource file from the jar, but also can overwrite the resource file in the jar.

[Java]View Plaincopy
    1. url url =  class. class.getresource (
    2. urlconnection  urlconnection= Url.openconnection ();   
    3. //read resource file   
    4. Inputstream inputstream=urlconnection.getinputstream ();   
    5. bufferedreader in=new bufferedreader (new  inputstreamreader (Inputstream, "Utf-8");   
    6. span class= "comment" >//write resource file   
    7. outputstream outputstream= Urlconnection.getoutputstream ();   
    8. printstream printstream=new  printstream (outputstream);   

Add: Just tested, use URL, urlconnection to get the output stream (outputstream) of the resource file in jar, prompt java.net.UnknownServiceException:protocol doesn ' t support output because the resource file method in the overwrite jar above is not so.

We can change the angle, do not merely have to read and write the resource file in the jar, only read the resource file in the jar when the software starts the program for the first time, and then back it up to the user's home directory or the user's current directory, then read and write the resource files in the user directory. First we package the resource file into the jar, the first time the program starts, it still reads the resource file information from the jar (obviously it can be implemented), and saves the read information into memory (for example, every time the program is started, the resource file information is read to the list or map collection), Updates to the resource files during the run of the program are updates to the list and map, and when the program is closed for the first time, the saved resource information in memory is written to the System.getproperty ("User.home") User home directory (or System.getproperty ( "User.dir") in the user's current directory, and generates a file that is identical to the resource file in the jar, which is read and written from the user directory's resource file at the start of the program. Only when the resource file in the user directory does not exist (where the program can judge it) does it read from the resource file in the jar, so the resource file in the jar is just the original backup function.

Of course, there are 2 questions (1): Every time the program is installed on a new machine, the Read resource file information is the raw resource information in the jar, we may have updated it halfway, Workaround: Package The updated resource file once again into the jar (2): Since each update to the resource file information is an update to the corresponding memory data, only when the program is closed to write back to the resource file, there is no change with the write, this may result in such a consequence, if the program is not very robust, the program Midway Bug is not responding, at this time can only force shutdown, Be sure to cause updated resource information not to be written back into the resource file!!! Solution: Each time to update the memory resource information immediately after the write back to the file, Lee: To ensure that the program bug after the resource file is still up-to-date, the disadvantage: This will cause frequent write file operations, program performance is reduced, (not necessarily oh, try the specific program, because it is a resource file, generally will not update very frequently)

(5) using java.util.jar.JarFile????? Never tried.

Reads the contents from a jar file and then writes back a jar file. First through a jarfile file = new Jarfile (fileName), and then File.entries () can get an iterator to the inner element of a jar file. With this iterator we can get all the jarentry, and then through InputStream is = Jarfile.getinputstream (jarentry), this jarentry input stream can be obtained. Finally, the contents of IS are jaroutputstream out = new Jaroutputstream (new FileOutputStream (Distjar)); The Out of out.write (int data) method to write to the target jar file.

(GO) Java reads the resource file from the jar package

Related Article

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.