使用idea时候遇到的一些输出文件或者读取文件路径问题

读取resources路径下的文件:

private static void getFile() {
    InputStream inputStream = Ctest.class.getClassLoader().getResourceAsStream("k/kk.txt");
    InputStreamReader isr = new InputStreamReader(inputStream);
    BufferedReader br = new BufferedReader(isr);
    try {
        while (br.ready()) {
            String s = br.readLine();
            System.out.println(s);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

文件位置:这个config被标记为resources类型,它会在classes path目录中


下面通过Java加载Properties文件来深入说明:
Java里加载Properties文件都是通过Java.util包里的Properties类的load()方法来加载一个Properties配置文件,load()方法需要接收一个文件输入流,而InputStream的构建需要Java.io.File对象,即new FileInputStream(new File(path));现在问题就集中在如何动态获取

Java里加载Properties文件都是通过Java.util包里的Properties类的load()方法来加载一个Properties配置文件,load()方法需要接收一个文件输入流,而InputStream的构建需要Java.io.File对象,即new FileInputStream(new File(path));现在问题就集中在如何动态获取这个路径。
下面以一个示例来说明吧。如图:

 使用idea时候遇到的一些输出文件或者读取文件路径问题_第1张图片

现在ActionFactory类里需要读取src目录下的config.properties文件。我们知道,java web项目编译后src目录对应的是应该是WEB-INF下的classes目录,所以我们可以先获取到ActionFactory.class文件,再根据相对路径采用../一步一步返回上一级得到config.properties文件的路径,于是有了第一种写法:
InputStream stream = this.getClass().getResourceAsStream("../../../../config.properties");//这里的this指的是ActionFActory类
pro.load(stream);
当然我们也可以通过类加载器根据一个相对路径返回一个文件输入流,即ClassLoader的getResourceAsStream方法。我们知道项目里的所有java文件编译后最终都是相对于WEB-INF下的classes目录存放的,而config.properties文件发布后的路径刚好是以classes目录为根目录。
所以我们通过项目里的类获取类加载器从而得到文件流,于是又有了第二种写法:
InputStream stream = this.getClass().getClassLoader().getResourceAsStream("config.properties");
pro.load(stream);
注意这里的this指的是ActionFActory类,当然你可以把它换成项目里的其他自定义类,因为项目里类虽不同,但都是使用的同一类
加载器。但是还要注意一点的是,注意我上面绿色标识的内容,是其他自定义类,而不能换成其他任意类。比如java.lang.Thread类就不行。这是你肯定会有这个疑问:为什么通过Thread类得不到类加载器?这个还得从JVM加载类说起。JVM启动时会首先使用JVM默认的系统类加载器帮我们加载一些jar,那到底JVM都自动帮我们加载了那些JAR文件到内存去了呢?具体请看图:

 使用idea时候遇到的一些输出文件或者读取文件路径问题_第2张图片

也就是说,如图所示红色方框表示的jar里的所有类.getClassLoader()得到的都是null,因为它们都是由JVM系统类加载器加载的,而Java的安全机制是不允许你获取系统类加载器对象的。
理解了上面那些,那我们还可以这样写:
InputStream stream=Thread.currentThread().getClass().getResourceAsStream("/config.properties");
但不能这样写:
InputStream stream = Thread.currentThread().getClass().getClassLoader().getResourceAsStream("config.properties");
但可以这样写:
InputStream stream = this.getClass().getClassLoader().getResourceAsStream("config.properties");
InputStream stream = new FileInputStream("/config.properties");  //相对于项目web-inf/classes目录
为什么 我就不再解释了吧。
如果是在web项目中,我们还可以这样写:
InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream("config.properties");
不过servlet已经帮我们封装了,我们一般这样写:
ServletContext.getRealPath("/")  这里的斜杠是相对与项目部署后的WebRoot为根目录。


写文件:

如果事web项目,这个System.getProperty("user.dir")的结果,就是tomcat的bin目录,这是在项目启动的时候,我是tomcat容器,所以,这个就是的结果就是tomcat的bin目录;要是在java代码中跑,那这个路径就是你这个项目的工作空间目录(不是项目被引用的路径,比如我的项目路径是E:\JavaLearn\Springboot\startDemo\spboot,但它是被工作空间为E:\IdeaWorkSpace的idea引用的,那么得到的路径不是项目本身的路径);还有就是jar包的工程,是项目的绝对地址(jar包所在路径)。

private static void createFile() {
    String property = System.getProperty("user.dir");
    try {
        BufferedWriter b=new BufferedWriter(new FileWriter(new File(property+"/createFile.txt")));
        b.write("--writer");
        b.close();
    } catch (IOException e) {
        e.printStackTrace();
    }

}

如果在springboot的日志配置文件中使用./的方式那么这个路径特性和上面一样:要是在java代码中跑,那这个路径就是你这个项目的工作空间目录(不是项目被引用的路径,比如我的项目路径是E:\JavaLearn\Springboot\startDemo\spboot,但它是被工作空间为E:\IdeaWorkSpace的idea引用的,那么得到的路径不是项目本身的路径);还有就是jar包的工程,是项目的绝对地址(jar包所在路径)。


name="logback.logdir" value="./logs"/>
name="logback.appname" value="tgmlog"/>

name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
    
    class="ch.qos.logback.classic.filter.ThresholdFilter">
        Error
    
    
    ${logback.logdir}/${logback.appname}.log




你可能感兴趣的:(idea基础)