java 资源文件的读取

Java将配置文件当作一种资源(resource)来处理,并且提供了两个类来读取这些资源,一个是Class类,另一个是ClassLoader类。

gradle 项目 项目目录结构 

用Class类加载资源文件

public InputStream getResourceAsStream(String name)

查找具有给定名称的资源。查找与给定类相关的资源的规则是通过定义类的 class loader 实现的。此方法委托此对象的类加载器。如果此对象通过引导类加载器加载,则此方法将委托给 ClassLoader.getSystemResourceAsStream(java.lang.String)。 >

在委托前,使用下面的算法从给定的资源名构造一个绝对资源名:

如果 name 以 ‘/’ 开始 (‘\u002f’),则绝对资源名是 ‘/’ 后面的 name 的一部分。 否则,绝对名具有以下形式: modified_package_name/name 其中 modified_package_name 是此对象的包名,该名用 ‘/’ 取代了 ‘.’ (‘\u002e’)。

用ClassLoader类加载资源文件

public InputStream getResourceAsStream(String name)

返回读取指定资源的输入流。

完整demo

package test.mybatis;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/**
 * Created on 2016/11/14 0014.
 *
 * @author zlf
 * @since 1.0
 */
public class ResourceLoader {

    ClassLoader defaultClassLoader;
    ClassLoader systemClassLoader;

    ResourceLoader() {
        try {
            //初始化类加载器
            systemClassLoader = ClassLoader.getSystemClassLoader();
        } catch (SecurityException ignored) {
            // AccessControlException on Google App Engine
        }
    }

    public static void main(String[] args) throws IOException {
        ResourceLoader resourceLoader = new ResourceLoader();
        resourceLoader.loadProperties1();//ClassLoader
        resourceLoader.loadProperties2();//classLoader
        resourceLoader.loadProperties3();//class
        resourceLoader.loadProperties4();//class
        resourceLoader.loadProperties5();//class
        resourceLoader.loadProperties6();//mybatis中调用系统classLoader
        resourceLoader.loadProperties7();//mybatis中调用系统classLoader

    }

    public void loadProperties1() throws IOException {
        try (
                InputStream input = ResourceLoader.class.getClassLoader().getResourceAsStream("test/mybatis/test.properties");
        ) {
            printProperties(input);
        }

    }

    public void loadProperties2() throws IOException {
        try (
                InputStream input = ResourceLoader.class.getClassLoader().getResourceAsStream("test.properties");
        ) {
            printProperties(input);
        }

    }

    public void loadProperties3() throws IOException {
        try (
                InputStream input = ResourceLoader.class.getResourceAsStream("test.properties");
        ) {
            printProperties(input);
        }

    }

    public void loadProperties4() throws IOException {
        try (
                InputStream input = ResourceLoader.class.getResourceAsStream("/test.properties");
        ) {
            printProperties(input);
        }

    }

    public void loadProperties5() throws IOException {
        try (
                InputStream input = ResourceLoader.class.getResourceAsStream("/test/mybatis/test.properties");
        ) {
            printProperties(input);
        }

    }

    public void loadProperties6() throws IOException {
        ClassLoader classLoader = new ClassLoader() {
        };
        try (
                InputStream input = getResourceAsStream("test/mybatis/test.properties");
        ) {
            printProperties(input);
        }

    }

    public void loadProperties7() throws IOException {
        try (
                InputStream input = getResourceAsStream("test.properties");
        ) {
            printProperties(input);
        }

    }

    public InputStream getResourceAsStream(String resource) {
        return getResourceAsStream(null, resource);
    }

    public InputStream getResourceAsStream(ClassLoader classLoader, String resource) {
        return getResourceAsStream(resource, getClassLoaders(classLoader));
    }
    //用5个类加载器一个个查找资源,只要其中任何一个找到,就返回
    InputStream getResourceAsStream(String resource, ClassLoader[] classLoader) {
        for (ClassLoader cl : classLoader) {
            if (null != cl) {
                // try to find the resource as passed
                InputStream returnValue = cl.getResourceAsStream(resource);

                // now, some class loaders want this leading "/", so we'll add it and try again if we didn't find the resource
                if (null == returnValue) {
                    returnValue = cl.getResourceAsStream("/" + resource);
                }

                if (null != returnValue) {
                    return returnValue;
                }
            }
        }
        return null;
    }

    private void printProperties(InputStream input) throws IOException {
        Properties properties = new Properties();
        properties.load(input);
        System.out.println(properties.getProperty("name"));
    }

    //一共5个类加载器
    ClassLoader[] getClassLoaders(ClassLoader classLoader) {
        return new ClassLoader[]{
                classLoader,
                defaultClassLoader,
                Thread.currentThread().getContextClassLoader(),
                getClass().getClassLoader(),
                systemClassLoader};
    }
}

参考链接:

 

 

 

 

本文主要讲解和总结java读取properties/xml等资源文件的几种方法,以备来日使用时翻阅。无论是Servlet、Struts或者Spring、Hibernate,配置资源文件都是必不可少的一项工作,Java中主要提供了提供了2个类来读取资源文件,一个是Class类,一个是ClassLoader类。我们一步步来分析,要获取一个文件的内容,那第一步肯定是要先获取文件的路径,第二步才是读取文件内容。

 

     本文地址:http://blog.csdn.net/chen_zw/article/details/18771897

 

      步骤一:获取资源文件路径

       java的Web项目结构相信大家应该都很熟悉,它大概是这样的:

       

       如上图所示,它主要分为了3部分,一个是source folder(src目录下),一个是output folder(build目录下),最后一个是deploy path(WebRoot) ,可能大家的命名不一样,但这3部分对应的功能是一致的。想修改这3部分对应的文件目录,可以选中项目,右键选properties,然后选中Java Build Path进行修改,如下图所示:

       

        首先说下source folder目录,这个目录下存放的是项目java源码,也就是可阅读、可编写的代码。而output folder目录则存放着java源码编译后生成的字节码,是.class文格式的,最后是deploy path目录,这是javaWeb项目独有的,主要存放的是Web相关的jar包、配置文件和网页资源等。我们可能将要读取的资源文件放在在source folder(src )或者deploy path(WebRoot )目录下,而两者的读取方式也是不同的。

        我们先来看看放在source folder(src )目录下的资源文件如何读取的吧,假设资源文件放置在这里:

          

 

[java] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. public class PropertiesUtil {  
  2.       
  3.     /** 
  4.      * @Description: 我们使用Class.getResourceAsStream(String path)方法来获取资源文件 
  5.      * @author: chenzw  
  6.      * @CreateTime: 2014-1-25 下午7:02:40 
  7.      * @param args  
  8.      * @throws  
  9.      */  
  10.     public static void main(String[] args) {  
  11.         /* path中不以'/'开头表示该路径是相对路径,相对于当前类所在的目录  */  
  12.         InputStream is = PropertiesUtil.class.getResourceAsStream("cfg/jdbc.properties");  
  13.         // 等同于 InputStream is = this.getClass().getResourceAsStream("cfg/jdbc.properties"); --this.getClass()不能在static方法中使用  
  14.           
  15.         /* path中以'/'开头表示该路径是绝对路径,相对于classpath的绝对路径 */  
  16.         InputStream is2 = PropertiesUtil.class.getResourceAsStream("/com/util/cfg/jdbc.properties");  
  17.         // 等同于 InputStream is2 = this.getClass().getResourceAsStream("/com/util/cfg/jdbc.properties"); --this.getClass()不能在static方法中使用  
  18.         // 等同于 InputStream is2 = Thread.currentThread().getClass().getResourceAsStream("/com/util/cfg/jdbc.properties");  
  19.           
  20.         /* 使用getClassLoader()表示该路径是相对于classpath目录的相对路径*/  
  21.         InputStream is3 = PropertiesUtil.class.getClassLoader().getResourceAsStream("com/util/cfg/jdbc.properties");  
  22.         // 等同于 InputStream is3 = this.getClass().getClassLoader().getResourceAsStream("com/util/cfg/jdbc.properties"); --this.getClass()不能在static方法中使用  
  23.                 // 等同于 InputStream is3 = Thread.currentThread().getContextClassLoader().getResourceAsStream("com/util/cfg/jdbc.properties");  
  24.   
  25.         //这3种方式获取的资源文件是同一个。  
  26.     }  
  27.   
  28. }  

 

          再来看看放在WebRoot目录下的资源文件是怎么读取的,假设资源文件存放在这里:

 

          

 

     步骤二:读取资源文件

 

[java] view plain copy
 
  1. package com.util;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.InputStream;  
  5. import java.util.Properties;  
  6.   
  7. public class PropertiesUtil {  
  8.       
  9.     /** 
  10.      * @throws IOException  
  11.      * @Description: 我们使用Class.getResourceAsStream(String path)方法来获取资源文件 
  12.      * @author: chenzw  
  13.      * @CreateTime: 2014-1-25 下午7:02:40 
  14.      * @param args  
  15.      * @throws  
  16.      */  
  17.     public static void main(String[] args) throws IOException {  
  18.         //资源文件路径的多种获取方法详见步骤一  
  19.         InputStream is = PropertiesUtil.class.getResourceAsStream("cfg/jdbc.properties");  
  20.           
  21.         Properties ps = new Properties();  
  22.         //加载properties资源文件  
  23.         ps.load(is);  
  24.         System.out.println(ps.getProperty("jdbc.url"));  
  25.         System.out.println(ps.getProperty("jdbc.user"));  
  26.         System.out.println(ps.getProperty("jdbc.pass"));  
  27.     }  
  28.   
  29. }  

 

 
 
posted @ 2017-08-08 13:47  穆穆兔兔  阅读(367)  评论(0编辑  收藏  举报