getResourceAsStream()
是java中用于加载资源文件的方法之一。
它是 ClassLoader
和 Class
类提供的方法,用于从类路径(ClassPath)中获取资源文件并返回一个输入流 (InputStream
)。这个方法常用于加载配置文件,模板文件,图片,音频等各种类型的资源。
方法签名:
InputStream getResourceAsStream(String name);
参数:
name
: 表示要加载的资源文件的路径,可以是相对路径或绝对路径。对于相对路径,其起始点通常是调用 getResourceAsStream()
方法的类或类加载器的位置,需要看是YouClassName.class.getResourceAsStream()
调用, 还是 YouCalssName.class.getClassLoader().getResourceAsStream()
调用。具体细节看下文。返回值:
InputStream
对象,允许你以字节流的方式读取资源文件的内容。注意事项:
getResourceAsStream()
方法在查找资源文件时,会根据调用它的类或类加载器的位置来查找资源。如果资源文件不在相应的类路径下,可能会导致找不到资源的情况。/
开头表示从类路径的根目录开始查找资源,不以 /
开头表示从调用它的类所在的包路径开始查找资源。ClassLoader
)// 假设要加载名为"config.properties"的配置文件
InputStream inputStream = YourClassName.class.getResourceAsStream("/config.properties");
// 使用BufferedReader读取配置文件内容
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
// 处理异常
}
注:YourClassName
是当前类的类名,用于定位类路径。可以通过这种方式加载任何类型的资源文件,并以输入流的形式读取其内容,无需关心资源文件的具体位置。
ClassLoader
)/**
* zip 压缩文件部署
* @throws IOException
*/
@Test
public void deployProcessByZip() throws IOException {
// 定义zip输入流
InputStream inputStream = this.getClass() // getClass() 返回:表示此对象的运行时类的Class对象。
.getClassLoader() // 返回:装入此对象表示的类或接口的类装入器。
.getResourceAsStream("process/process.zip");
ZipInputStream zipInputStream = new ZipInputStream(inputStream);
// 流程部署
Deployment deployment = repositoryService.createDeployment()
.addZipInputStream(zipInputStream)
.name("请假申请流程")
.deploy();
System.out.println("流程部署id: " + deployment.getId());
System.out.println("流程部署名称:" + deployment.getName());
}
案例:
this.getClass() // getClass() 返回:表示此对象的运行时类的Class对象。
.getClassLoader() // 返回:装入此对象表示的类或接口的类装入器。
.getResourceAsStream("process/process.zip");
this.getClass() // getClass() 返回:表示此对象的运行时类的Class对象
.getResourceAsStream("process/process.zip");
this.getClass().getClassLoader().getResourceAsStream("process/process.zip")
: 这种方式使用类加载器(ClassLoader
)来加载资源文件。类加载器是用于加载类的机制,并且每个类加载器都有自己的类加载路径。getResourceAsStream
方法的路径是相对于类加载器的根路径。因此,"process/process.zip"
这个路径将相对于类加载器的根路径来定位资源文件。
在一些情况下,特别是当使用不同的类加载器(例如自定义类加载器)加载类时,this.getClass().getClassLoader().getResourceAsStream("process/process.zip")
可能更可靠,因为它直接使用类加载器的路径,不受当前类的位置的影响。
this.getClass().getResourceAsStream("process/process.zip")
: 这种方式使用当前类的类加载器来加载资源文件。getResourceAsStream
方法的路径是相对于当前类所在的包路径(package path)。换句话说,它会在当前类的包路径下寻找资源文件。
这种方式适用于当前类和资源文件在同一个包路径下的情况。如果资源文件与当前类在不同的包路径下,或者资源文件位于类加载器的根路径(Classpath根目录)下,这种方式可能会失败,因为它是相对于当前类所在的包路径来定位资源文件。
所以,总的来说,两种方式都可以加载资源文件,但要根据你的具体情况来选择哪种方式更合适。如果你需要在不同类加载器的情况下加载资源文件或者资源文件位于类加载器的根路径下,推荐使用this.getClass().getClassLoader().getResourceAsStream("process/process.zip")
;如果资源文件与当前类在同一个包路径下,那么 this.getClass().getResourceAsStream("process/process.zip")
是更直观的选择。
当我看到这里,还是有一点不明白,在this.getClass().getClassLoader().getResourceAsStream("process/process.zip")
调用中,getResourceAsStream
方法的路径是相对于类加载器的根路径。那么,这个类加载的根路径是哪里呢?
ClassLoader
的根路径是在哪里?类加载器的根路径,也称为Classpath根路径,是类加载器用于查找类和资源文件的基本路径。在Java中,有三种主要的类加载器:
java.lang.Object
、java.lang.String
等。sun.misc.Launcher$ExtClassLoader
表示的,负责加载Java的扩展库(extensions)。${java.home}/lib/ext/
目录,其中${java.home}
是JDK的安装目录。sun.misc.Launcher$AppClassLoader
表示的,负责加载应用程序的类和资源文件。java.class.path
系统属性指定的,包括当前工作目录和所有被指定的JAR文件或目录。对于系统类加载器,其类路径包含了Classpath根路径。在绝大多数情况下,Classpath根路径是项目构建(如Maven或Gradle项目)的src/main/resources
目录。在这个目录下的资源文件,通过getClass().getResourceAsStream()
或者getClass().getClassLoader().getResourceAsStream()
来访问。
请注意,类加载器可以是层次结构的,当一个类加载器无法加载类或资源时,它会委托给父类加载器来尝试加载。因此,资源的查找顺序是从下往上,即从当前类加载器的类路径开始,然后向上层级查找,直到找到资源或到达Bootstrap ClassLoader。