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

时间: 2025-01-01 03:07:22

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

动态加载JavaScript文件的两种方法_javascript技巧

这篇文章主要为大家详细介绍了动态加载JavaScript文件的两种方法,感兴趣的小伙伴们可以参考一下 第一种便是利用ajax方式,把script文件代码从背景加载到前台,而后对加载到的内容经过eval()实施代码.第二种是,动静创建一个script标签,配置其src属性,经过把script标签插入到页面head来加载js,相当于正在head中写了一个<script src="..."></script>,只可是这个script标签是用js动静创建的 比喻说是我们

动态加载script文件的两种方法_javascript技巧

动态加载script到页面大约有俩方法 第一种就是利用ajax方式,把script文件代码从后台加载到前台,然后对加载到的内容通过eval()执行代码.第二种是,动态创建一个script标签,设置其src属性,通过把script标签插入到页面head来加载js,相当于在head中写了一个<script src="..."></script>,只不过这个script标签是用js动态创建的 比如说是我们要动态地加载一个callbakc.js,我们就需要这样一个scr

Java加载资源文件时的路径问题的解决办法_java

加载资源文件比较常用的有两种: 一.用ClassLoader,说到这里就不得不提一下ClassLoader的分类,java内置的ClassLoader主要有三种, 第一种是根类加载器(bootstrap class loader),用C++来编写,负责将一些关键的Java类,如java.lang.Object和其他一些运行时代码先加载进内存中. 所负责加载的包:BootStrp------>JRE/lib/rt.jar 第二种是扩展类加载器(ExtClassLoader),由java类编写,负责

Spring加载properties文件的两种方式

版权声明:尊重博主原创文章,转载请注明出处哦~http://blog.csdn.net/eson_15/article/details/51365707 目录(?)[+]         在项目中如果有些参数经常需要修改,或者后期可能需要修改,那我们最好把这些参数放到properties文件中,源代码中读取properties里面的配置,这样后期只需要改动properties文件即可,不需要修改源代码,这样更加方便.在spring中也可以这么做,而且Spring有两种加载properties文件

动态加载JS文件的三种方法_javascript技巧

直接看实例.例1 重新加载js文件 复制代码 代码如下: function loadJs(file) {            var head = $("head").remove("script[role='reload']");            $("<scri" + "pt>" + "</scr" + "ipt>").attr({ role: 're

动态加载js文件的三种方法

<script language="网页特效"> function importfn(){  var head = document.getelementsbytagname("head")[0];  var script = document.createelement('script');  script.id = 'sid';  script.type = 'text/javascript';  script.src = '../js/alertt

Android实现listview动态加载数据分页的两种方法_Android

在android开发中,经常需要使用数据分页,比如要实现一个新闻列表的显示,或者博文列表的显示,不可能第一次加载就展示出全部,这就需要使用分页的方法来加载数据,在android中Handler经常用来在耗时的工作中,它接收子线程发送的数据,并使用数据配合更新UI,AsyncTask是在一个线程中执行耗时操作然后把结果传给UI线程,不需要你亲自去管理线程和句柄. 一.使用Handler+线程方法1.基础知识Handler在android系统中,主要负责发送和接收消息,它的用途主要有以下两种: (1

Android清除工程中无用资源文件的两种方法_Android

一.调用Android lint命令查找出没有用到的资源,并生成一个清单列表: 命令:lint –check "UnusedResources" [project_path] > result.txt 执行完之后会生成一个清单文件,内容如下: 二.使用代码自动删除无用的文件: public class DelAction { public static void main(String[] args) throws IOException { String projectPath

Android清除工程中无用资源文件的两种方法

一.调用Android lint命令查找出没有用到的资源,并生成一个清单列表: 命令:lint –check "UnusedResources" [project_path] > result.txt 执行完之后会生成一个清单文件,内容如下: 二.使用代码自动删除无用的文件: public class DelAction { public static void main(String[] args) throws IOException { String projectPath