Java加载资源文件的两种方法

简介:

处理配置文件对于Java程序员来说再常见不过了,不管是Servlet,Spring,抑或是Structs,都需要与配置文件打交道。Java将配置文件当作一种资源(resource)来处理,并且提供了两个类来读取这些资源,一个是Class类,另一个是ClassLoader类。

 

 

当我们自己的程序需要处理配置文件时(比如xml文件或properties文件),通常会遇到两个问题:

 

(1)我的配置文件应该放在哪里?

(2)怎么我的配置文件找不到了?

 

 

在了解了Java加载资源文件的机制后,以上这两个问题便迎刃而解了。

 

对于第一个问题,答案是:请将你的资源文件放在classpath里,如果资源文件在jar中,请将该jar文件也加到classpath里面。

 

对于第二个问题,就得看你是使用的是哪个类(Class还是ClassLoader)来加载资源文件了,所以接下来分别讨论一下Class类和ClassLoader类对于资源文件的加载机制。

 

(一)用Class类加载资源文件

 

通过调用Class类的getResourceAsStream方法来加载资源文件:

public InputStream getResourceAsStream(String pathToConfigFile);

 

该方法接收一个String类型的参数(pathToConfigFile)来表示资源文件的地址,如果加载成功,则返回该资源文件的输入流(InputStream),如果失败,则返回null。重要的是,在传入pathToConfigFile参数时,有两种方式,第一种方式为绝对定位方式,即pathToConfigFile以"/"开头,此时Java以classpath为根目录,直接加上pathToConfigFile来搜索资源文件。第二种方式为相对定位方式,即pathToConfigFile不以"/"开头,此时资源文件的全路径应该为:调用getResourceAsStream方法的类的package路径加上pathToConfigFile。(在将package转为目录时将"."变成"/")

 

举个例子,在IntelliJ Idea中创建一个java工程,目录结构如下:

 

该工程里有两个resources文件夹,一个位于davenkin文件夹下,一个直接位于src文件夹下。第一个resources文件夹下有一个config.properties文件,其内容为:

 

 

name = ConfigUnderDavenkin

 

 

第二个resources文件夹下也有一个config.properties文件,其内容为:

 

 

name = ConfigUnderSrc

 

 

在davenkin包下定义ResourceLoader.java来加载资源文件:

 

package davenkin;

import java.io.IOException; import java.io.InputStream; import java.util.Properties; public class ResourceLoader { public static void main(String[] args) throws IOException { ResourceLoader resourceLoader = new ResourceLoader(); resourceLoader.loadProperties1(); } public void loadProperties1() throws IOException { InputStream input = null; try { input = Class.forName("davenkin.ResourceLoader").getResourceAsStream("/resources/config.properties"); //also can be this way: //input = this.getClass().getResourceAsStream("/resources/config.properties"); } catch (ClassNotFoundException e) { e.printStackTrace(); } printProperties(input); } private void printProperties(InputStream input) throws IOException { Properties properties = new Properties(); properties.load(input); System.out.println(properties.getProperty("name")); } }

 

 

 

输出结果为第二个resources文件夹下config.properties的内容:

 

 

ConfigUnderSrc

 

 

原因在于(请注意ReourceLoader.java文件中的红色部分):我们给出的资源文件路径(/resources/config.properties)以"/"开头,即使用的是绝对定位方式,所以找到的是直接在classpath下的resources文件夹。如果去掉资源文件文件路径前的"/",则采用的是相对定位方式,此时应该输出davenkin/resources/config.properties文件的内容。

 

 

(二)用ClassLoader类加载资源文件

 

ClassLoader类也提供和Class类相同的加载方法:

 

public InputStream getResourceAsStream(String pathToConfigFile);

 

用ClassLoader加载配置文件时,pathToConfigFile均不能以"/"开头,在查找时直接在classpath下进行查找。Class类在查找资源文件时,也是代理(delegate)给ClassLoader完成查找功能的,请参考Java官方文档

 

在使用Class和ClassLoader加载资源文件时,有几种区别细微的方法,修改ResourceLoader.java文件如下:

 

package davenkin;

import java.io.IOException; import java.io.InputStream; import java.util.Properties; public class ResourceLoader { public static void main(String[] args) throws IOException { ResourceLoader resourceLoader = new ResourceLoader(); resourceLoader.loadProperties1(); resourceLoader.loadProperties2(); resourceLoader.loadProperties3(); resourceLoader.loadProperties4(); resourceLoader.loadProperties5(); resourceLoader.loadProperties6(); } public void loadProperties1() throws IOException { InputStream input = null; try { input = Class.forName("davenkin.ResourceLoader").getResourceAsStream("/resources/config.properties"); } catch (ClassNotFoundException e) { e.printStackTrace(); } printProperties(input); } public void loadProperties2() throws IOException { InputStream input = null; input = this.getClass().getResourceAsStream("/resources/config.properties"); printProperties(input); } public void loadProperties3() throws IOException { InputStream input = this.getClass().getResourceAsStream("resources/config.properties"); printProperties(input); } public void loadProperties4() throws IOException { InputStream input = this.getClass().getClassLoader().getResourceAsStream("resources/config.properties"); printProperties(input); } public void loadProperties5() throws IOException { InputStream input = ClassLoader.getSystemResourceAsStream("resources/config.properties"); printProperties(input); } public void loadProperties6() throws IOException { InputStream input = ClassLoader.getSystemClassLoader().getResourceAsStream("resources/config.properties"); printProperties(input); } private void printProperties(InputStream input) throws IOException { Properties properties = new Properties(); properties.load(input); System.out.println(properties.getProperty("name")); } }

 

 

 

以上程序输出结果为(请仔细揣摩,稍不小心(比如多加了一个"/"或少加了一个"/"),就会报NullPointerException异常,表明你的资源文件没有找到):

 

 

ConfigUnderSrc

ConfigUnderSrc ConfigUnderDavenkin ConfigUnderSrc ConfigUnderSrc ConfigUnderSrc
相关文章
|
10月前
|
Java Maven Spring
Java Web 应用中,资源文件的位置和加载方式
在Java Web应用中,资源文件如配置文件、静态文件等通常放置在特定目录下,如WEB-INF或classes。通过类加载器或Servlet上下文路径可实现资源的加载与访问。正确管理资源位置与加载方式对应用的稳定性和可维护性至关重要。
286 7
|
Java
如何解决使用若依前后端分离打包部署到服务器上后主包无法找到从包中的文件的问题?如何在 Java 代码中访问 jar 包中的资源文件?
如何解决使用若依前后端分离打包部署到服务器上后主包无法找到从包中的文件的问题?如何在 Java 代码中访问 jar 包中的资源文件?
1198 0
|
XML Java 数据库
Java-利用Spring提供的Resource/ResourceLoader接口操作资源文件
Java-利用Spring提供的Resource/ResourceLoader接口操作资源文件
174 0
|
XML 存储 Java
Java读写资源文件类Properties
Java读写资源文件类Properties
223 0
Java读写资源文件类Properties
|
Java
Java 中如何获取 classpath 下资源文件?
Java 中的资源有多种,如File,URL, InputStream等,本篇将介绍在Java中获取classpath下的资源文件的几种方式
859 0
|
前端开发 Java Linux
Java获取外部资源文件的几种方式和区别
Java有很多获取外部资源的方式。本篇文章将使用流(Stream)的方式为大家演示&排惑!
2852 0
|
Java Spring Maven
【java】获取解析资源文件的方法
关于资源文件的读取,有很多种方法,下面补充了多种方法 1.java.util.ResourceBundle 使用java自带的util包下的ResourceBundle类获取,使用方法最简单 //获取资源文件中键值对 ResourceBundle bundle = ResourceBundle.
1171 0