Java reads the resource file under resources

There should always be such a requirement in Web projects. Put some files in the resources directory of maven project.
For example, some configuration files, resource files, etc.
There are several ways to read files. This paper will summarize the common reading methods and explain what should be paid attention to.

When the packaged project is wap, POM XML needs to be configured:

<resources>
    <resource>
        <directory>${project.basedir}/src/main/resources/cert</directory>
        <filtering>true</filtering>
    </resource>
</resources>

Care should also be taken to prevent content from being modified:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-resources-plugin</artifactId>
    <configuration>
        <!--avoid pfx The contents of the file were tampered with by the compiler-->
        <nonFilteredFileExtensions>
            <nonFilteredFileExtension>pfx</nonFilteredFileExtension>
        </nonFilteredFileExtensions>
    </configuration>
</plugin>

1, Read files through ClassLoader

ClassLoader.getResourceAsStream() gets the file input stream

public void loadPropertiesFile() throws IOException {
    Properties properties = new Properties();
  properties.load(this.getClass().getClassLoader().getResourceAsStream("conf.properties"));

    log.info(properties.getProperty("file.max.size"));

}

ClassLoader.getResourceAsStream() gets the URL of the file

public void loadJsonFile() throws IOException {
    //Get the URL of the file = this getClass(). getClassLoader(). getResource("json/city_code.json");

    String content = FileUtils.readFileToString(new File(url.getPath()),     StandardCharsets.UTF_8);

    log.info(content);

}

2, Read files through Class

Class.getResourceAsStream() gets the input stream of the file

public void loadPropertiesFile() throws IOException {
    Properties properties = new Properties();

    properties.load(this.getClass().getResourceAsStream("/conf.properties"));

    log.info(properties.getProperty("file.max.size"));

}

Class.getResourceAsStream() gets the URL of the file

public void loadJsonFile() throws IOException {
        //Gets the URL of the file 
        URL url = this.getClass().getResource("/json/city_code.json");

        String content = FileUtils.readFileToString(new File(url.getPath()), StandardCharsets.UTF_8);

        log.info(content);

}

Class.getResourceAsStream() and classloader There is a significant difference between getresourceasstream() and getresourceasstream(). When the former is loaded, it needs to add a "/" before the file path.

3, The Spring project reads the File through resourceutils The GetFile () method can read the File

public void loadJsonFile() throws IOException {
  //Gets the URL of the file 
  File file = ResourceUtils.getFile("classpath:json/city_code.json");

  String content = FileUtils.readFileToString(file, StandardCharsets.UTF_8);

  log.info(content);

}

adopt ClassPathResource Get input stream ClassPathResource Construction parameters of path No distinction between absolute paths,"json/city_code.json" perhaps "/json/city_code.json"Can successfully obtain the input stream of the file.



public void loadJsonFil1(){
  ClassPathResource classPathResource = new ClassPathResource("json/city_code.json");

  InputStream inputStream = classPathResource.getInputStream();

  String content = IOUtils.toString(inputStream, StandardCharsets.UTF_8);

  log.info(content);

}    

4, How to distinguish whether to add "/"

When using these methods to read files, you need to pass in a file path. As for whether to add a "/" in front of the path, people are often confused. Here is a summary. If the file is read through Class, the path needs to start with "/". Reading files through ClassLoader or tool classes provided by Spring actually does not need to precede the path with "/".

5, Summary

The best solution to these problems is to turn over the source code, and then debug at breakpoint to see the values of various variables in the process of reading files. By looking at the source code, you can not only solve the problem, but also help yourself figure out the relationship and difference between these ways of reading files.

Here is a section of the source code of the two methods of Class. The following conclusions can be drawn from the code. Both Class and ClassLoader can read files, but Class reads files through ClassLoader.

Class needs to go through the resolveName method before reading the file, and resolveName will resolve the file path. If the path starts with "/", delete "/". If the path does not start with "/", the package name prefix will be spliced before the file path, and then the file will be read with the new file path.

    public java.net.URL getResource(String name) {
        name = resolveName(name);
        ClassLoader cl = getClassLoader0();
        if (cl==null) {
            // A system class. return ClassLoader.getSystemResource(name);
        }
        return cl.getResource(name);
    }

    public InputStream getResourceAsStream(String name) {
        name = resolveName(name);
        ClassLoader cl = getClassLoader0();
        if (cl==null) {
            // A system class. return ClassLoader.getSystemResourceAsStream(name);
        }
        return cl.getResourceAsStream(name);

    }

    /*** Add a package name prefix if the name is not absolute Remove leading "/"* if name is absolute*/

    private String resolveName(String name) {
        if (name == null) {
            return name;
        }
        if (!name.startsWith("/")) {
            Class c = this;
            while (c.isArray()) {
                c = c.getComponentType();
            }
            String baseName = c.getName();
            int index = baseName.lastIndexOf('.');
            if (index != -1) {
                name = baseName.substring(0, index).replace('.', '/') +"/"+name;
            }
        } else {
            name = name.substring(1);
        }
        return name;
    }


 

Keywords: Java

Added by andrests on Fri, 24 Dec 2021 19:00:30 +0200