处理配置文件对于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

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

  1. xml文件 加载properties文件的两种方法与注意事项

    1.遇到的问题: 配置redisSpringContext.xml 时,遇到 properties加载失败,提示BeanDefinitionStoreException  和   java.lang. ...

  2. 动态加载script文件的两种方法

    第一种就是利用ajax方式,把script文件代码从后台加载到前台,然后对加载到的内容通过eval()执行代码.第二种是,动态创建一个script标签,设置其src属性,通过把script标签插入到页 ...

  3. 加载xib文件的两种方式

    一.加载xib文件的两种方式 1.方法一(NewsCell是xib文件的名称) NSArray *objects = [[NSBundle mainBundle] loadNibNamed:@&quo ...

  4. Spring加载properties文件的两种方式

    在项目中如果有些参数经常需要修改,或者后期可能需要修改,那我们最好把这些参数放到properties文件中,源代码中读取properties里面的配置,这样后期只需要改动properties文件即可, ...

  5. Java加载资源文件几种方法

    from: http://andyzhu.blog.51cto.com/4386758/775836/ import java.net.URL; import org.springframework. ...

  6. windows/tomcat 修改java虚拟机JVM以utf-8字符集加载class文件的两种方式

      1.情景展示 做了这么长时间的java开发,但是,你知道JVM是以怎样的编码加载.解析class文件的吗? 我们知道,通常情况下,我们会将java文件的字符集修改成utf-8,这样,理所当然地就认 ...

  7. java加载资源文件

    className.class.getResourceAsStream 用法: 第一: 要加载的文件和.class文件在同一目录下,例如:com.x.y 下有类Test.class ,同时有资源文件c ...

  8. [ARM-Linux开发]Linux下加载.ko驱动模块的两种方法:insmod与modprobe

    假设要加载的驱动程序模块名为SHT21.ko 加载驱动模块 方法一:  进入SHT21.ko驱动模块文件所在的目录,然后直接  insmod SHT21.ko  即可 方法二:  将SHT21.ko文 ...

  9. 加载properties文件的三种方法

    源代码: package a.one; import java.io.FileInputStream; import java.io.InputStream; import java.util.Pro ...

随机推荐

  1. C#操作Excel知识点

    近期在使用C#操作excel,主要是读取excel模板,复制其中的模板sheet页,生成多个sheet页填充相应数据后另存到excel文件,所用到的知识点如下. 一.添加引用和命名空间 添加Micro ...

  2. netty 入门二 (传输bytebuf 或者pojo)

    基于流的数据传输:在基于流的传输(如TCP / IP)中,接收的数据被存储到套接字接收缓冲器中. 不幸的是,基于流的传输的缓冲区不是数据包的队列,而是字节队列. 这意味着,即使您将两个消息作为两个独立 ...

  3. http2.4简单配置

    前言: 上一篇博文说到了http的发展以及http完整请求响应的工作流程. 一.开篇: 从最简单的静态服务器开始. 之前说过,http是应用层协议,必定会在用户空间体现出具体的应用程序.常见的http ...

  4. 冒泡排序-Python与PHP实现版

    Python实现 import random a=[random.randint(1,999) for x in range(0,33)] # 冒泡排序,python中数组是按引用传递的,会直接在原数 ...

  5. mysql 查询各数据库的占用大小

    select TABLE_SCHEMA, concat(truncate(sum(data_length)/1024/1024,2),' MB') as data_size, concat(trunc ...

  6. windows下忘记mysql的root密码解决方法(图文)

    在windows下忘记mysql的root密码对于很对新手来说,也是会经常遇到的,我也刚好遇到啦,参考网上的解决办法,自己又整理啦一下. 1.首先需要查看mysql的服务是否启动. 打开cmd窗口,输 ...

  7. oracle 物化视图 job

    在oracle数据库里边,创建物化视图之后,系统在DBMS_jobs文件夹下,会自动创建相应的job,右键执行job的时候报错如下: 问题:ORA-12012: 自动执行作业 198 出错 ORA-1 ...

  8. OC的内存管理和@class

    1. 基本原理 1. 什么是内存管理 ➢ 移动设备的内存极其有限,每个app所能占用的内存是有限制的 ➢ 当app所占用的内存较多时,系统会发出内存警告,这时得回收一些不需要再使用的内存空间.比如回收 ...

  9. apache mysql无法启动解决办法

    最近在调试几个代码,需要不停的启动关闭服务器和mysql.在连续的几次开关后,无法启动了,每次启动后就直接关闭. 刚开始是怀疑是不是端口被占用了,查看端口后,并没有端口被占用的情况.查看mysql错误 ...

  10. 【17-06-16】Java入门测试题,测测你基础知识掌握程度(附答案及个人解析)

    描述 前几天在知乎里看到一份这样的题,当时只是随便做了一下,对了一下答案.昨天又有了一份进阶的题,里面有些还是需要记录一下,于是就从这个入门的题开始. 题目和答案来自阿里云大学 - 知乎专栏 题目 现 ...