Use a class loader or class object to read the file (the reference path is the folder after compilation, out or target folder)

  • The following content is summarized by me using Maven project, so it will be different from the project directory of ordinary projects.
  • Relative path: The root directory of the project to start the search. (But when we are actually developing, the more files we read are not placed directly in the folder in our project, but in our module)
  • Similarly, if we create the file b.txt directly, the file will be created in the root directory of the project

 File file = new File("b.txt");
        file.createNewFile();
        System.out.println(file.getAbsolutePath());//F:\IdeaProjects\workspace\review\b.txt

1. Use class object to read files

getResourceAsStream() method in Class

  • The resource mentioned in the explanation below is the file we are looking for, and the file is equivalent to b.txt above
  • The following Module is a class in Java, because everything in Java is an object and is a module class. Module also has a method called getResourceAsStream
  • The following class loader is the class loader
  • Find a resource with a given name
  • If the class is in a named module , this method will try to find the resource in the module . This is done by delegating to the module’s class loader findResource(String, String) method, calling it with the module name and the absolute name of the resource. Resources in a named module are subject to the encapsulation rules specified in the Module.getResourceAsStream method, so when the resource is a non-“.class” resource in the package and the resource is not open to the caller’s module, this method returns null .
  • Otherwise, if the class is not in the named module, the rules for searching for resources associated with a given class are implemented by the class’s defining class loader. This method delegates to the class loader of this class object. If this class object is loaded by the bootstrap class loader, this method delegates to ClassLoader.getSystemResourceAsStream.
  • Constructs an absolute resource name from the given resource name before delegation using the following algorithm:
  • If the name begins with ‘/’ (‘\\/’), the absolute name of the resource is the part of the name that follows ‘/’.
  • Otherwise, the absolute name is of the form:
  • modified_package_name/name
  • Where modified_package_name/name is the package name of the object, use ‘/’ instead of ‘.’ (‘\\.’)
  • Parameter: name – the name of the resource
  • Returns: InputStream object; if no resource with this name is found, the resource is in a package that is not at least open to the caller module, or the security manager denies absolute access to the resource
  • Throws: NullPointerException – if the name is empty
  • Since 1.1
  • See: Module.getResourceAsStream ( String )
  • Modified version 9

  • If the file corresponding to the entered path does not exist, return null
  • The reference is the path of the .class bytecode file corresponding to the Class object
  • F: \ IdeaProjects \ workspace \ review \ reflect \ target \ classes \ com \ csdn \ clz \ Person.class
  • Because I created a Maven project, the compiled files are in the target, so as long as the files we want to read are placed in the clz folder, they can be read. In fact, they are the same as the Person.class bytes Code files can be read if they are in the same folder
  • If it is not a Maven project, the compiled files will be in the out folder
  • F: \ IdeaProjects \ workspace \ review \ reflect \ target \classes \ com \ csdn \ clz \ reflect.txt

package com.csdn.clz;
import com.csdn.pojo.Student;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.*;

/**
 * Use class object to read files
 */
public class LoaderDemo3 {
    public static void main(String[] args) throws IOException {

        File file = new File("b.txt");
        file.createNewFile();
        System.out.println(file.getAbsolutePath());//F:\IdeaProjects\workspace\review\b.txt

// new File("reflect/src/main/java/com/csdn/clz/reflect.txt").createNewFile();

        //Relative path: start searching from the root directory of the project
        FileInputStream fis = new FileInputStream("b.txt");
        System.out.println(fis);//java.io.FileInputStream@776ec8df

        Class<Person> clz = Person.class;
        InputStream stream1 = clz.getResourceAsStream("b.txt");
        System.out.println(stream1);//null

        Class<Person> per = Person.class;
        InputStream inputStream = per.getResourceAsStream("reflect.txt");
        System.out.println(inputStream);//java.io.BufferedInputStream@7ba4f24f

        Class<Student> stu = Student.class;
        InputStream inputStream1 = stu.getResourceAsStream("../clz/reflect.txt");
        System.out.println(inputStream1);//java.io.BufferedInputStream@3b9a45b3

    }
}
@Data
@NoArgsConstructor
@AllArgsConstructor
class Person {
    private String name;
    private int age;
}

2. Use class loader to read files

Call the getResourceAsStream(String path) method in ClassLoader

  • The reference path is: the path in the out folder after the current module is compiled (if it is a Maven project, the reference is the path in the target folder)
  • If it is an out folder, the reference is the path starting under the module folder under the out folder

  • If it is a Maven project, the reference is the path starting from the classes file in the target folder

package com.csdn.clz;
import com.csdn.pojo.Student;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.*;
/**
 * Use class loader to read files
 */
public class LoaderDemo3 {
    public static void main(String[] args) throws IOException {

        Class<Person> clz = Person.class;
        ClassLoader appClassLoader = clz.getClassLoader();
        InputStream stream = appClassLoader.getResourceAsStream("reflect.txt");
        System.out.println(stream);//null

        InputStream stream2 = appClassLoader.getResourceAsStream("com/csdn/clz/reflect.txt");
        System.out.println(stream2);//java.io.BufferedInputStream@7cca494b

        Class<Student> studentClass = Student.class;
        ClassLoader classLoader = studentClass.getClassLoader();
        InputStream stream3 = classLoader.getResourceAsStream("com/csdn/clz/reflect.txt");
        System.out.println(stream3);//java.io.BufferedInputStream@7ba4f24f

    }
}
@Data
@NoArgsConstructor
@AllArgsConstructor
class Person {
    private String name;
    private int age;
}

3. Which method of reading is better?

  • It is better to use a class loader because it is more stable
  • Because class objects are used to read files, and the class objects used are different, our reference paths are different.

  • But we use the class loader to read, no matter how the class object changes, our reference path is the same

4. How to solve the trouble caused by the above path problem?

  • Always thinking about the path we want to refer to greatly reduces the efficiency of our development, so the development tools uniformly set up a folder to store these configuration files, which are the files we want to read
  • In the Maven project, a folder named resources will be automatically generated for us. We only need to put the files to be read under the resources folder. When we execute the code, that is, after running the compilation , the development tool will automatically put the file to be read into the folder corresponding to the path to be referenced above