转载--JAVA读取文件最佳实践
- 1. 前言
Java应用中很常见的一个问题,如何读取jar/war包内和所在路径的配置文件,不同的人根据不同的实践总结出了不同的方案,但其他人应用却会因为环境等的差异发现各种问题,本文则从原理上解释最佳实践。
- 2. 参考方案
2.1.log4j
log4j读取配置的代码是:
PropertyConfigurator.configure(“log4j.properties”);
实际执行的文件读取是:
FileInputStream istream = new FileInputStream(configFileName);
也就是执行环境${PWD}中查找文件,这个路径与new File()的路径是一样的。
2.2.hibernate
hibernate读取配置的代码是:
Configuration configuration = new Configuration().configure(“hibernate.cfg.xml”);
实际执行的文件读取是:
String stripped = resource.startsWith(“/”) ? resource.substring(1) : resource;
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream stream = classLoader.getResourceAsStream(stripped);
是通过类加载器的相对路径来查找文件,这种方式好处是可以读取jar中的文件,而且是new File()无法模拟的。
- 3. 方案分析
3.1.方案对比
相对而言,hibernate的文件读取更加实用,主要因为可以读取普通文件,也可以读取jar/war中的文件,相对更通用。
3.2.参考文档
更常见的情况是使用Class.getResourceAsStream(String name),实际上最终会调用ClassLoader.getSystemResourceAsStream,但很多人对于getResourceAsStream并不完全理解,所以很疑惑有些时候需要在路径上加上“/”,有些时候不用。
简单来说ClassLoader的基础路径是固定,而Class的基础路径则不相同,所以ClassLoader都是相对路径,Class读取则存在绝对路径和相对路径两种情况。
Class.getResourceAsStream文档中有解释:
(1)如果name以“/”开头,则是读取${PWD}下的文件。应用与读取jar同级别路径的文件如hibernate.cfg.xml。
(2)如果name不以“/”开头,则是读取Class所在路径package下的文件。应用于读取与Class有关的文件如*.hbm.xml。
- 4. 实践应用
4.1.最优方案
由于Class.getResourceAsStream会继续调用ClassLoader的方法,那么建立一个单例的ClassLoader是最优的方案,比如hibernate的实现。
结合maven来说,src/main/resources中的文件都使用ClassLoader.getSystemResourceAsStream(“log4j.properties”)方式读取,对于*.hbm.xml等ORM映射文件等则需要加上包路径,如“com/zheezes/*.hbm.xml”。
4.2.最佳实践
不过由于getClass()方式更简洁,而且性能损失非常小,所以实际使用中,直接调用getClass().getResourceAsStream()的方式更为常用。
结合maven来说,src/main/resources中的文件都使用绝对路径getClass().getResourceAsStream(“/log4j.properties”)方式读取,对于*.hbm.xml等ORM映射文件则一般在PO的Class中直接使用相对路径“*.hbm.xml”来读取。
最新文章
- Postgresql死锁处理
- Win7下手动卸载oracle 11G
- C++ Primer----一个关于 vector 的有趣的问题
- MoreLinq和Linq
- iOS:自定义工具栏、导航栏、标签栏
- linux 下的对拍
- iOS开发之监听键盘高度的变化 分类: ios技术 2015-04-21 12:04 233人阅读 评论(0) 收藏
- inform表单验证,正则表达式,用户名,身份证,密码,验证码
- c++数据类型漫谈
- idea 去除xml文件sql语句背景色
- Oracle DB
- JavaScript Dom 绑定事件
- 22.一个球从100m高度自由下落,每次落地后返跳回原高度的一半,再反弹。求它在第10次落地时,共经过多少米,第10次反弹多高。
- Java基础之Java 修饰符
- solus 系统 - 安装编译工具
- 01List.ashx(班级列表动态页面)
- 如何将Win10 的环境变量页面设置用在win7上面?
- Tomcat 7.x/8.x 优化
- 利用SQL表生成按日期序列的唯一ID
- Servlet实现数字字母验证码图片(二)