使用 类加载器 或者 类对象 读取文件(参考的路径都是编译以后的文件夹,out 或者 target 文件夹 )

news/2024/5/19 6:59:26 标签: 反射, 类对象, 类加载器
  • 以下内容 本人都是 用 Maven 工程总结的 ,所以会和普通项目的项目目录不太一样。
  • 相对路径:项目根目录 开始查找。( 但是在我们真正开发的时候,我们读到的更多的文件并不是直接放在我们项目里面这个文件夹里面,而是放在我们模块里面
  • 同理可得,我们直接创建 文件 b.txt 会在项目的根目录下创建文件

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

 1、使用 类对象 读取文件

 Class 中的 getResourceAsStream() 方法

  • 下面解释中提到的 资源 就是我们要找的 文件,文件就相当于上面的b.txt
  • 下面的 Module 是 java 中的一个类,因为在 Java 中万物皆对象,是一个模块类,Module也有一个方法是 getResourceAsStream
  • 下面的 类装入器 就是 类加载器
  • 查找具有给定名称的资源
  • 如果该 位于命名 模块 中,则此方法将尝试在 模块 中查找 资源。这是通过委托给模块的类装入器 findResource(String,String)方法完成的,用模块名和资源的绝对名称调用它。命名模块中的资源受 Module.getResourceAsStream方法中指定的封装规则的约束,因此当资源是包中的非 ".class"资源,且该资源未对调用者的模块打开时,此方法返回 null。
  • 否则,如果该类不在命名模块中,则搜索与给定类关联的资源的规则由类的定义类装入器实现。此方法委托给此类对象的类装入器。如果这个类对象是由引导类加载器加载的,则该方法委托给ClassLoader.getSystemResourceAsStream.
  • 在委托之前,使用以下算法从给定的资源名称构造绝对资源名:
  • 如果名称以  '/' ('\u002f')  开头,则资源的绝对名称是名称中  '/'  后面的部分。
  • 否则,绝对名称为以下形式:
  • modified_package_name/name
  • 其中 modified_package_name/name 是该对象的包名,用 '/'  代替  '.' ('\u002e')
  • 参数:name ——  资源的名称
  • 返回:InputStream 对象;如果没有找到具有此名称的资源,则该资源位于至少未对调用方模块打开的包中,或者安全管理器 拒绝 绝对 该资源的访问
  • 抛出:NullPointerException ——   如果名称为空
  • 自从  1.1  开始
  • 参见:Module.getResourceAsStream ( String )
  • 修改后的  9  版本
  • 如果输入的路径对应的文件不存在,返回 null
  • 参考的是 Class 类对象 对应的  .class 字节码文件 所在的路径
  • F: \ IdeaProjects \ workspace \ review \ reflect \ target \ classes \ com \ csdn \ clz  \ Person.class
  • 因为我创建的 是 Maven 工程,所以编译以后的文件在 target 里面,所以只要把 我们要读取的文件放在  clz 这个文件夹里面就可以读取到,其实就是和 Person.class字节码文件在同一个文件夹下,就可以被读取到
  • 如果不是 Maven 工程,编译以后的文件在 out 文件夹里
  • 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.*;

/**
 * 使用 类对象 读取文件
 */
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();

        //相对路径:项目的根目录开始查找
        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、使用 类加载器 读取文件 

调用 ClassLoader 里的  getResourceAsStream(String path)方法

  • 参考的路径是:当前模块编译以后,在 out 文件夹里的路径(如果是 Maven 工程,则参考的是 target 文件夹里的路径 )
  • 如果 是 out 文件夹,则参考的是 out 文件夹下 的 模块文件夹 下开始的路径

  • 如果是 Maven 工程 ,则参考的是 target 文件夹下 的 classes 文件下开始的路径

package com.csdn.clz;
import com.csdn.pojo.Student;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.*;
/**
 * 使用类加载器  读取文件
 */
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、两者用哪种方式读取更好一些?

  •  但是我们用 类加载器 读取,不管 类对象 怎么改变,我们的参考路径都是一样的

4、怎样解决以上 路径问题 带来的 麻烦呢?

  • 总是去思考我们要参考的路径,极大的降低了我们开发的效率,所以开发工具统一 设置了一个文件夹来存储这些配置文件,也就是我们要读取的文件
  • 在 Maven 工程中,会自动给我们生成一个叫 resources 这个名字的文件夹,我们只需要把要读取的文件放在 resources 这个文件夹下面,当我们执行代码后,也就是运行编译后,开发工具会自动把要读取的文件放入以上要参考的路径所对应的文件夹下面

 


http://www.niftyadmin.cn/n/5112117.html

相关文章

java--Consumer的使用

一、目的 因为代码中用到了Consumer &#xff0c;所以特地来梳理其对应的用法以及总结。 二、介绍 Consumer 是一个函数式接口&#xff0c;它位于java.util.function 包中&#xff0c;它定义了一个名为accept 的抽象方法&#xff0c;该方法接受一个参数并且不返回任何结果。 …

C/C++文件操作————写文件与读文件以及通讯录的改进 (保姆级教学)

个人主页&#xff1a;点我进入主页 专栏分类&#xff1a;C语言初阶 C语言程序设计————KTV C语言小游戏 C语言进阶 C语言刷题 欢迎大家点赞&#xff0c;评论&#xff0c;收藏。 一起努力&#xff0c;一起奔赴大厂。 目录 1.前言 2.写文件函数与读文件函数 …

【汇编语言-王爽】第七章:更灵活的定位内存地址的方法

知识点 and指令&#xff1a;逻辑与指令&#xff0c;按位进行与运算。通过该指令可将操作对讲的相应位设为0。or指令&#xff1a;逻辑或指令&#xff0c;按位进行或运算。通过该指令&#xff0c;可将操作对象的相应位设为1。A的ASCII码是41H&#xff0c;a的ASCII码是61H。换成二…

华为云HECS云服务器docker环境下安装nacos

华为云HECS云服务器&#xff0c;安装docker环境&#xff0c;查看如下文章。 华为云HECS安装docker-CSDN博客 一、拉取镜像 docker pull nacos/nacos-server二、宿主机创建挂载目录 执行如下命令&#xff1a; mkdir -p /usr/local/nacos/logs mkdir -p /usr/local/nacos/con…

理解电路:从电报机到门电路,我们如何做到“千里传信”?

目录 背景 从信使到电报&#xff0c;我们怎么做到“千里传书”&#xff1f; 理解继电器&#xff0c;给跑不动的信号续一秒 小结 背景 所有最终执行的程序其实都是使用“0”和“1”这样的二进制代码来表示的。我们知道&#xff0c;对应的整数和字符串&#xff0c;其实也是用…

Kettle查询表数据循环到目标表

简介&#xff1a;Kettle工具有一种业务场景是动态查询数据库中某张表的某个字段&#xff0c;将该字段当做循环变量&#xff0c;循环整个作业。下面就是记录该步骤。 一、思路 首先生产环境中我们需要做的一个业务就是&#xff1a; 按品牌循环执行&#xff1a;step3step4&…

Java-io(输入/输出)

文章目录 绪论输入流输出流File类文件输入 / 输出流字节输入输出流字符输入输出流 End 绪论 首先如果我们在Java编写的一个程序中获得了想要的某种结果&#xff0c;那么在程序结束后&#xff0c;这个结果还存在嘛&#xff1f;不存在的&#xff0c;因为在Java程序运行时&#x…

生成包含10个随机字母或数字的字符串,然后统计每个字符的出现次数

from random import choices from string import ascii_letters, digitsx .join(choices(ascii_lettersdigits, k10)) d dict() # 创建空字典 for ch in x:d[ch] d.get(ch, 0) 1 # x中有ch字符,个数1,并作为字典的值 print(x) print(d)也可以使用collections模块的defaul…