走出Java资源加载的迷宫

简介: 走出Java资源加载的迷宫 Java开发中常常要加载各种各样的资源文件,如property文件,xml配置文件,图片文件等等。 Java的资源加载策略选择比较多,很多资源加载方法都是基于不同的项目配置,没有一种资 源加载方法是万能的。

走出Java资源加载的迷宫

Java开发中常常要加载各种各样的资源文件,如property文件,xml配置文件,图片文件等等。

Java的资源加载策略选择比较多,很多资源加载方法都是基于不同的项目配置,没有一种资

源加载方法是万能的。首先来看看Java中的几种常见的资源加载方法:

 

一:通过ResourceBundle类来实现资源加载

这种方式通常被用来加载多语言支持的property文件,Java语言通过ResourceBundle可以非

常好的支持国际化。假设在默认为英文的系统中有语言资源文件mybundle_en.properties,则

调用代码如下:

ResourceBundle myBundle =ResourceBundle.getBundle("mybundle");

资源文件mybundle_en.properties的位置应该在sourcefolder的根目录下,假如资源文件位于

包路径com.mybundle.test下则上述代码应该改写为:

ResourceBundle myBundle =ResourceBundle.getBundle("com.mybundle.test.mybundle");

 

二:通过Class类的getResourceAsStream()方法来实现资源加载

这种加载方式同时是最常用也是最容易让开发者搞错的方法,getResourceAsStream()方法使用

默认文件名加载资源时,要求资源必须与Class文件同时相同的包路径。加载代码如下:

client.getClass().getResourceAsStream("mybundle.properties");

 

三:通过ClassLoader的getResourceAsStream()来实现资源文件加载

通过ClassLoader来加载资源文件是一种非常有效和实用的方法,只要资源位于classpath的路

径下面,ClassLoader都可以通过适当的策略来找到你要加载的资源。但是应该注意的是如果你

的资源位于SourceFloder的根目录,如下代码就可以完成:

this.getClass().getClassLoader().getResource("mybundle.properties");

如果你的资源文件位于独立的config文件中,只需要把config配置到classpath的变量中,然后使

用如下代码即可:

this.getClass().getClassLoader().getResource("config/mybundle.properties");

 

三种资源加载方式比较与总结:

方法

参数

失败时行为

用法示例代码

ClassLoader.

getResourceAsStream()

绝对路径加载时候不需要反斜杠/

Silent (return null)

This.getCalss().

getClassLoader().

getResourceAsStream(“

some/pkg/resource.prpperties

”);

Class.

getResourceAsStream()

有反斜杠/表现为绝对路径

Silent(return null)

This.getClass().

getResourceAsStream(“

resource.properties”);

ResourceBundle.

getBundle()

不需要反斜杠/, .已经暗示绝对路径

.properties为其默认的文件扩展名

Throws unchecked

 java.util.MissingResource

Exception

ResourceBundle.getBundle(

“some.pkg.resource”)

 资源加载策略说明:

不同的开发者对资源文件的管理千差万别,有的喜欢把它们放在不同的类路径下面,有的喜

欢放在单一的config文件下,没有一种方法是错误的。但是为了能够正确的加载到你需要的

资源文件,永远应该记得把资源文件夹的路径配置做为classpath的一部分,如果资源文件没

有位于你的source folder之内。否则你不得不通过额外的手段来配置与加载你的资源文件。

基于上述的总结,完成了一个资源加载的UtilityClass, 让你从此不再对Java中资源加载怀有好奇

与恐惧之心。

Resource Loading Utility Class源代码如下:

import java.io.InputStream;
import java.util.Locale;
import java.util.Properties;
import java.util.ResourceBundle;

public class CommonResourceLoader {

		/**
		 * please use this method if property files located at same package with CommonResourceLoader
		 * Java class
		 * 
		 * @param PropertiesName
		 * @return
		 */
        public static Properties loadPropertyFile(String PropertiesName) {

              Properties props = new Properties();

              try
              {
                  InputStream in = CommonResourceLoader.class.getResourceAsStream(PropertiesName);
                 if (in != null)
                 {
                    props.load(in);
                 } 
                 else
                 {
                    throw new IllegalArgumentException("No file exists for" + PropertiesName);
                 }
              }
              catch (Exception e)
              {
                 e.printStackTrace();
              }

              return props;
        }
        
        /**
         * if the properties file is located at obj's package, please use it
         * @param obj
         * @param PropertiesName
         * @return
         */
        public static Properties loadPropertyFile(Class obj,  String PropertiesName) {

              Properties props = new Properties();

              try
              {
                  InputStream in = obj.getResourceAsStream(PropertiesName);
                 if (in != null)
                 {
                    props.load(in);
                 } 
                 else
                 {
                    throw new IllegalArgumentException("No file exists for" + PropertiesName);
                 }
              }
              catch (Exception e)
              {
                 e.printStackTrace();
              }

              return props;
        }
        
        /**
         * base name is file name if file located at class path root directory
         * base name is directory + file full name if file at some folder inside class path list.
         * eg: myPro.properties
         * project structure
         * pro--src
         *  |    |---com.mytest.pkg
         *  |    |               |-----Hello.java
         *  |    |               |-----test.properties
         *  |---myPro.properties
         *  baseName= com/mytest/pkg/test.properties if load test.properties
         *  baseName= myPro.properties if load myPro.properties
         *
         * @param baseName
         * @return
         */
        public static Properties loadCurrentPropertyFile(String baseName) {
            Properties props = new Properties();

            try
            {
                InputStream in = CommonResourceLoader.class.getClassLoader().getResourceAsStream(baseName);
               if (in != null)
               {
                  props.load(in);
               } 
               else
               {
                  throw new IllegalArgumentException("No file exists for" + baseName);
               }
            }
            catch (Exception e)
            {
               e.printStackTrace();
            }

            return props;
        }
        
        public static Properties loadSystemPropertyFile(String name, ClassLoader loader) {
            Properties props = new Properties();

            try
            {
            	if(loader == null)
            		loader = ClassLoader.getSystemClassLoader();
                InputStream in = loader.getResourceAsStream(name);
               if (in != null)
               {
                  props.load(in);
               } 
               else
               {
                  throw new IllegalArgumentException("No file exists for" + name);
               }
            }
            catch (Exception e)
            {
               e.printStackTrace();
            }

            return props;
        }
        
        /**
         * resourceURL is file name if file located at class path root directory
         * resourceURL is directory + file full name if file at some folder inside class path list.
         * eg: myPro.properties
         * project structure
         * pro--src
         *  |    |---com.mytest.pkg
         *  |    |               |-----Hello.java
         *  |    |               |-----test.properties
         *  |---myPro.properties
         *  resourceURL= com.mytest.pkg.test.properties if load test.properties
         *  resourceURL= myPro.properties if load myPro.properties
         *
         * @param baseName
         * @return
         */
        public static ResourceBundle loadResourceBundle(String resourceURL) {

                Locale locale = Locale.ENGLISH;
                ResourceBundle bundle = null;

                try {
                        bundle = ResourceBundle.getBundle(resourceURL, locale);
                        if (bundle == null) {
                                throw new IllegalArgumentException("No file exists for" + resourceURL);
                        }
                } catch (Exception e) {
                        e.printStackTrace();
                }

                return bundle;
        }

}
特别说明:

这里的资源是指配置文件(xml,property等), 图片,Java程序运行需要的一切文本文件等等。


目录
相关文章
|
1月前
|
Java 程序员
JAVA程序员的进阶之路:掌握URL与URLConnection,轻松玩转网络资源!
在Java编程中,网络资源的获取与处理至关重要。本文介绍了如何使用URL与URLConnection高效、准确地获取网络资源。首先,通过`java.net.URL`类定位网络资源;其次,利用`URLConnection`类实现资源的读取与写入。文章还提供了最佳实践,包括异常处理、连接池、超时设置和请求头与响应头的合理配置,帮助Java程序员提升技能,应对复杂网络编程场景。
58 9
|
2月前
|
Java
Java开发实现图片地址检验,如果无法找到资源则使用默认图片,如何编码?
【10月更文挑战第14天】Java开发实现图片地址检验,如果无法找到资源则使用默认图片,如何编码?
65 2
|
1月前
|
Java 开发者
JAVA高手必备:URL与URLConnection,解锁网络资源的终极秘籍!
在Java网络编程中,URL和URLConnection是两大关键技术,能够帮助开发者轻松处理网络资源。本文通过两个案例,深入解析了如何使用URL和URLConnection从网站抓取数据和发送POST请求上传数据,助力你成为真正的JAVA高手。
58 11
|
2月前
|
Java
【Java】蚂蚁迷宫问题
【Java】蚂蚁迷宫问题
15 0
|
4月前
|
安全 Java 网络安全
【认知革命】JAVA网络编程新视角:重新定义URL与URLConnection,让网络资源触手可及!
【认知革命】JAVA网络编程新视角:重新定义URL与URLConnection,让网络资源触手可及!
48 2
|
5月前
|
缓存 前端开发 Java
在Java项目中实现跨域资源共享(CORS)
在Java项目中实现跨域资源共享(CORS)
|
6月前
|
Java
在Java中,死锁是指两个或多个线程互相等待对方释放资源,从而导致所有线程都无法继续执行的情况。
【6月更文挑战第24天】在Java并发中,死锁是多线程互相等待资源导致的僵局。避免死锁的关键策略包括:防止锁嵌套,设定固定的加锁顺序,使用`tryLock`带超时,避免无限等待,减少锁的持有时间,利用高级同步工具如`java.util.concurrent`,以及实施死锁检测和恢复机制。通过这些方法,可以提升程序的并发安全性。
45 1
|
6月前
|
Java
死锁是线程间争夺资源造成的无限等待现象,Java示例展示了两个线程各自持有资源并等待对方释放,导致死锁。`
【6月更文挑战第20天】死锁是线程间争夺资源造成的无限等待现象,Java示例展示了两个线程各自持有资源并等待对方释放,导致死锁。`volatile`保证变量的可见性和部分原子性,确保多线程环境中值的即时更新。与`synchronized`相比,`volatile`作用于单个变量,不保证原子操作,同步范围有限,但开销较小。`synchronized`提供更全面的内存语义,保证原子性和可见性,适用于复杂并发控制。
48 3
|
5月前
|
Java Go 调度
Java演进问题之协程和线程在资源占用和切换速度上不同如何解决
Java演进问题之协程和线程在资源占用和切换速度上不同如何解决
|
5月前
|
Java Docker 容器
Java演进问题之Java的资源占用如何解决
Java演进问题之Java的资源占用如何解决