Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to solve the problem that the project is packaged into a jar package and cannot read the files under src/main/resources?

2025-01-22 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly introduces "how to solve the problem that the project is packaged into a jar package and cannot read the files under the src/main/resources". In the daily operation, it is believed that many people have doubts about how to solve the problem when the project is packaged into a jar package and cannot read the files under the src/main/resources. The editor consulted all kinds of materials and sorted out a simple and useful method of operation. I hope it will be helpful to answer the question "how to solve the problem that the project is packaged into a jar package and cannot read the files under src/main/resources"! Next, please follow the editor to study!

I. Project scene

When reading files in a project, use a pit that appears in new File () and the resolution process

This problem is encountered not only when reading local files, but also when downloading text under a project (for example, under the src/main/resources directory).

II. Problem description Discovery problem

Original code

The code function is to use the FileUtils under the common.io package to read the file and put it in a string

String s = FileUtils.readFileToString (new File ("src/main/resources/holiday.txt"), "utf-8")

This path writing method new File ("src/main/resources/holiday.txt") has no problem running locally.

But there was a problem running in the server after packaging. Here is a screenshot of the error

You can see the log prompt in the server: java.io.FileNotFoundException: File 'holiday.txt' does not exist

That is, after packaging, the file cannot be found under the path src/main/resources configured at the beginning.

Analyze the problem

After the project is packaged, the files located in the resource directory, the most common is that various Spring configuration files will be packaged in the BOOT-INF/classes directory

While FIle is looking for it according to the original file path src/main/resources/holiday.txt', it is inevitable that the file cannot be found, so it will report an exception that the file cannot find.

In the process of locating the problem, it is found that here is an idea.

All the files in SpringBoot are in the jar package, and there is no actual path, so you can use the following ways

/ * is obtained through the ClassPathResource class. It is recommended to use this method in * springboot projects in SpringBoot, because there is not an actual path in the jar package to store files * * @ param fileName * @ throws IOException * / public void function6 (String fileName) throws IOException {ClassPathResource classPathResource = new ClassPathResource (fileName); InputStream inputStream = classPathResource.getInputStream (); getFileContent (inputStream) } Why can I find the path of the packaged file after using ClassPathResource?

The core of the above code is to instantiate the ClassPathResource object. Then call getInputStream to get the resource file

Let's analyze this code.

When ClassPathResource is instantiated, it initializes the classloader classLoader and loads all the paths used by the project into the classloader classLoader, including the jar of the java runtime environment, the jar in the Maven project, and the packaged jar of the current project (see the following figure)

When classPathResource.getInputStream gets the resource file, because we initialize a classLoader.

So classLoader is not empty, so the getResourceAsStream method is executed. Let's trace this method.

GetResource in the getResourceAsStream method is the actual business processing method, and we continue to delve into

The getResource method is shown in the figure below. The actual function is to call yourself recursively to continuously traverse the path under parent to get the corresponding resource file.

So who is parent? Let's move on.

Seeing here, we suddenly enlightened that this mysterious parent is the classloader classLoaderloader!

So the getResource method is to keep traversing the path under the classloader we created when we instantiated ClassPathResource! (corresponding to point 1)

III. Solutions

The original code to read the file is as follows

String s = FileUtils.readFileToString (new File ("src/main/resources/holiday.txt"), "utf-8")

Check the constructor of File to see if it can be constructed through InputStream

It doesn't work from the picture below.

Option one

And we find that org.apache.commons.io does not provide a method to read files with ClassPathResource as an input parameter.

So we have to write the way to read the file by hand.

The handwritten code is as follows

Mainly notice Resource resource = new ClassPathResource (fileName); is = resource.getInputStream ()

/ * * Java reads the contents of txt file * * @ param fileName resources directory file name (no directory is required) * @ return puts each line in list as a unit * / public static List readTxtFile (String fileName) {List listContent = new ArrayList (); InputStream is = null; InputStreamReader isr = null; BufferedReader br = null; String encoding = "utf-8" Try {Resource resource = new ClassPathResource (fileName); is = resource.getInputStream (); isr = new InputStreamReader (is, encoding); br = new BufferedReader (isr); String lineTxt = null; while ((lineTxt = br.readLine ())! = null) {listContent.add (lineTxt) } catch (IOException e) {e.printStackTrace ();} finally {try {br.close (); isr.close (); is.close ();} catch (IOException e) {e.printStackTrace () } return listContent;} scenario 2

This method is less intrusive to the code, and the core is to use FileUtils under common.io. The specific method is

Use FileUtils to copy the input stream obtained by ClassPathResource.getInputStream to a temporary file, and then read the temporary file

The disadvantage of this approach is that temporary files need to be created, and if the files to be read are too large, recreating the files and copying operations will consume a certain amount of space and time, affecting performance.

/ / Mode 2 uses FileUtils to copy the input stream obtained by ClassPathResource.getInputStream to a temporary file Resource resource = new ClassPathResource ("holiday.txt"); InputStream inputStream = resource.getInputStream (); File tempFile = File.createTempFile ("temp", ".txt"); FileUtils.copyInputStreamToFile (inputStream, tempFile); String s = FileUtils.readFileToString (tempFile, StandardCharsets.UTF_8); unexpected

There is another problem here, that is, the test project I use because some format files are specified in maven. The configuration is as follows

Because banner.txt is specified and files ending with xml and properties are packaged as resources. So the file holiday.txt is still not accessible after it is running.

The pom.xml file in question is as follows

Src/main/java * * / .xml src/main/resources * * / * .xml * / .properties * / banner.txt

The screenshot of the packaged resource file is as follows, from which you can see that holiday.txt has not been packaged.

Screenshot of the error after the program is run

Let's modify the specified packaged configuration * * / * .txt

After this configuration, we can package all the txt files under the classpath into the project, and the location of the files after packaging is as follows

Or we can remove the following code configuration from the project, which will package all the files under resources by default

Src/main/java * * / .xml src/main/resources * * / * .xml * * / .properties * * / .txt

After modifying the pom file, repackage the resource file (you can see from here that holiday.txt is packaged)

At this point, the study on "the project packaged into a jar package can not read the files under src/main/resources how to solve" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report