In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
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.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.