`
frank-liu
  • 浏览: 1682118 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java读取properties文件方法和对比

    博客分类:
  • java
阅读更多

简介

    我们在做一些Java应用开发的时候,会将很多环境特定的变量定义到一个配置文件中。比较常见的定义文件有xml, properties,甚至txt等格式的。在Java里有一个类似于标准配置格式的文件,就是.properties类型的文件。它主要用来存储一些名值对的内容,里面的内容都存成如propertyname=propertyvalue这种样式。读取properties文件的方法有很多种,网上也有大量的说明,这里主要针对两种典型的方式做一个对比。

问题场景

    现在假定我们有一个config.properties的文件,里面存有如下的内容信息:

dbpassword=password
database=localhost
dbuser=user

     我们希望通过程序来读取它的内容。

    粗粗一看,这问题实在是太简单了,且看我们的第一个方法:

File IO

    我们可以直接通过File Stream的经典方式来读文件,然后解析一把出来不就可以了么?这种实现的代码如下::

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

public class App {
	public static void main(String[] args) {
		Properties prop = new Properties();
		
		try {
			prop.load(new FileInputStream("config/config.properties"));
			
			System.out.println(prop.getProperty("database"));
			System.out.println(prop.getProperty("dbuser"));
			System.out.println(prop.getProperty("dbpassword"));
		} catch(IOException e) {
			e.printStackTrace();
		}
	}
}

     这部分代码几乎没什么可说的,就是通过创建一个java.util.Properties的对象,然后在指定properties文件之后通过FileInputStream读取它,将这个InputStream作为参数传给properties对象。properties对象的load方法就把结果解析出来了。我们执行它之后就会看到一个如下的结果:

localhost
user
password

     还有一个要注意的地方就是,我们在传递给FileInputStream的路径是当前的相对路径,也就是说我们必须把config.properties文件放到我class文件所在目录的一个config字目录下。

    现在,在考虑其他方式之前,我们看看FileInputStream这种方式的特点。我们读取properties文件的时候必须要知道它所在的路径。采用FileInputStream的时候我们必须将文件的路径传递给程序。否则程序找不到文件后会出现异常。考虑到我们的程序很多时候是编译后要部署到不同的生产环境的,如果每个环境不一样,难道我们每次都要来修改这个程序吗?或者说我们将配置文件所在的路径还要作为一个参数传给程序?这两种方式很明显不太合适。那么有没有什么法子比如说我不需要修改程序或者刻意传参数给程序就搞定了呢?另外一种方法可以达到这个理想的结果。

classloader

    采用classloader的方式主要是通过它的getResourceAsStream方法来实现加载properties文件。具体细节我们可以看如下的示例:

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

public class NewApp {
	public static void main(String[] args) {
		Properties prop = new Properties();
		
		try {
			prop.load(NewApp.class.getClassLoader().getResourceAsStream("config.properties"));
			
			System.out.println(prop.getProperty("database"));
			System.out.println(prop.getProperty("dbuser"));
			System.out.println(prop.getProperty("dbpassword"));
		} catch(IOException e) {
			e.printStackTrace();
		}
	}
}

     这里我们并没有指定一个特定的路径给classloader,我们只是将文件名直接传给了它。如果我们将config.properties文件和class文件放在同一个目录下,结果运行正常。如果我们将properties放到其他地方则会碰到如下的错误:

Exception in thread "main" java.lang.NullPointerException
        at java.util.Properties$LineReader.readLine(Properties.java:434)
        at java.util.Properties.load0(Properties.java:353)
        at java.util.Properties.load(Properties.java:341)
        at NewApp.main(NewApp.java:10)

     这是怎么回事呢?这是因为classloader每次会去classpath这些路径搜索需要装载的文件。如果不在这些路径下,则会报找不到文件的错误信息。所以说,只要我们将配置文件放在classpath的路径下,我们就可以保证它会被装载进来,而且程序就不会被改动了。这样就带来了一定的灵活性。比如说前面这个示例,如果我们将properties放到当前目录的config子目录下,该怎么装载它呢?

    我们需要指定这个路径为classpath就可以了,所以我们运行如下的命令:

java -cp c:\samplecode\config; NewApp

     我们将看到正常运行的结果。这里我们是将代码放在c:\samplecode这个路径下。仔细看看这种classloader装载的方法,其实它只是在一个指定的范围内来查找目标文件。我们在不同的环境下部署安装的时候则不需要去修改程序或给特定程序部分传参数来。我们只需要将需要加载的配置项文件配置到classpath中就可以。

    当然,除了classloader这种装载properties的方式,还有其他几种具体的方法,比如class.getResourceAsStream(), ResourceBundle.getBundle()等几种方法,他们的本质上和classloader的方式都差不多。

classpath的作用

    前面几个地方也一直提到classpath,那么这个classpath有什么作用呢?在哪些地方我们要用到它?这里也一并讨论一下。

    我们通常写的一些简单的程序,比如说只是通过console显示结果的,很可能没有留意到classpath的作用。它是指定class所在路径的。在一些需要引用到其他类库的情况下,我们需要这些类库所在的具体位置,比如说我们把一个jar包放在一个lib的文件夹下面了,我们希望程序编译或者执行的时候要能够引用到它。可是java怎么知道引用它呢?这就是classpath的作用了。java虚拟机通过搜索指定的classpath路径变量,它会在这些路径里搜索和尝试装载这些需要的类库。如果能够装载成功则可以保证程序的正常运行,否则会产生错误。

    所以说,classpath说白了就是一个指定类所在位置的路径以使得jvm可以识别和装载它们。

总结

    操作properties文件的方式有好几种,考虑到properties文件主要是用于针对不同环境进行特定配置的,所以我们必须要保证用一种灵活的方式来加载它。使用classloader等加载的话不需要修改程序,只是需要在部署的时候针对特定环境配置好classpath就可以了。

 

参考材料

http://www.javaworld.com/javaqa/2003-08/01-qa-0808-property.html?page=1

http://www.mkyong.com/java/java-properties-file-examples/

http://blog.csdn.net/pengpenglin/article/details/1682858

6
6
分享到:
评论
3 楼 frank-liu 2013-07-06  
alvin198761 写道
wosyingjun 写道
貌似有个ResourceBundle类读取属性文件挺方便的。。。

那个类就专门干这种事情的,比楼主上面的两个都要好用,而且还支持国际化

http://lavasoft.blog.51cto.com/62575/184605 这里有一篇文章,对ResourceBundle做了详细的介绍。感觉ResourceBundle支持的功能更加强大。
2 楼 alvin198761 2013-07-05  
wosyingjun 写道
貌似有个ResourceBundle类读取属性文件挺方便的。。。

那个类就专门干这种事情的,比楼主上面的两个都要好用,而且还支持国际化
1 楼 wosyingjun 2013-07-04  
貌似有个ResourceBundle类读取属性文件挺方便的。。。

相关推荐

    Properties 文件比较工具

    本项目提供了一个专门的“Properties文件比较工具”,它采用Java语言编写,能够帮助开发者快速检查和对比两个properties文件之间的差异,从而确保配置的一致性和正确性。 在Java中,`java.util.Properties`类是处理...

    好用的properties插件

    4. **多语言支持**:对于国际化(i18n)项目,`properties`插件可以方便地管理不同语言版本的资源文件,轻松切换和对比不同语言的文本。 5. **错误检查**:实时检查文件中的语法错误,确保文件的正确性。 6. **搜索...

    Java C# 语法 比较

    - Java和C#的类定义语法类似,但C#支持更多的特性,如属性(Properties)、索引器(Indexers)和事件(Events)。 - C#支持构造函数的参数默认值和可选参数。 - C#中的析构函数用`~`符号标记,但其功能与Java中的...

    PropertiesEditor

    3. **编码转换**:考虑到.Properties文件通常需要进行UTF-8、GBK等不同编码的转换,PropertiesEditor提供了便捷的编码转换功能,确保文件在不同系统和环境中都能正确读取。 4. **错误检查与修复**:插件能自动检测...

    Eclipse插件之properties编辑器.rar

    Properties文件是Java应用程序中用于存储配置信息的文本文件,通常用于国际化(i18n)和本地化(l10n)。这个rar压缩包“Eclipse插件之properties编辑器”显然提供了一个专门用于编辑这类文件的工具。 Properties编辑器...

    基于Java的实例源码-跨平台的文件同步工具 Capivara.zip

    1. **Java I/O与文件操作**:Java的java.io包提供了丰富的类用于读写文件、创建目录、删除文件等。Capivara将利用这些API来处理文件系统的操作。 2. **文件比较**:为了实现同步,Capivara需要比较不同位置的文件...

    java源码:跨平台的文件同步工具 Capivara.rar

    Java的`java.io.File`类提供了文件和目录的遍历方法,而文件内容的比较可能需要用到哈希算法或逐字节比较。 4. **异步与并发**:为了提高性能,Capivara可能采用了异步处理和并发策略。Java的`java.util.concurrent...

    spring 启动时加载不同的文件

    // 读取deploy.properties文件 try { prop.load(inputStream); String dataSource = prop.getProperty("DATE_SOURCE"); if ("0".equals(dataSource)) { // 加载dbconn.properties this.setLocations(new ...

    java编程思想读书笔记

    - Java中提供了丰富的API来进行文件读写操作,如`FileInputStream`、`FileOutputStream`等。 - 为了提高效率,Java还支持缓冲流(如`BufferedInputStream`和`BufferedOutputStream`)来减少磁盘访问次数。 - 对于...

    java实现两个mysql同步主库的数据

    9. **项目配置**:整个Java项目应该包含必要的配置文件,如数据库连接配置、定时任务配置等。这些配置可以使用如Properties或YAML格式。 10. **测试与监控**:确保在实际环境中进行充分的测试,并设置监控,以便于...

    JAVA经典教材笔记

    - 泛型类与泛型方法:使用泛型增强类和方法的功能。 - 泛型擦除:编译后泛型信息会被擦除。 - **泛型操作范例** - 泛型容器的操作:ArrayList等。 - 泛型算法:Collections.sort(List)等。 #### 第十一章:Java...

    Developing java Beans

    - **`BeanInfo`接口**:描述了JavaBeans的所有可公开属性、事件和方法的信息。 - **提供额外的`BeanInfo`对象**:扩展默认的`BeanInfo`以提供更多功能。 - **内省环境**:在运行时自动检测JavaBeans的能力。 7. ...

    Java基础教程.md.pdf

    - 继承使得一个类可以继承另一个类的属性和方法。 ##### 8.8 方法的重写(Override) - 子类重写父类的方法,用以提供特定的实现。 ##### 8.9 super与this关键字 - `super`用于访问父类的属性或方法。 - `this`用于...

    国际化插件

    3. **版本控制**:方便跟踪不同语言版本的更新,支持版本对比和合并。 4. **预览功能**:有些插件允许预览不同语言下的应用界面,确保翻译的准确性和适应性。 5. **自动化工具**:插件可能集成了一些自动化工具,如...

    Java敏感词过滤Java敏感词过滤

    - 使用 `Properties` 类读取配置文件。 - 构建正则表达式模式字符串。 ##### 2. 敏感词过滤逻辑 ```java private static String doFilter(String str) { Matcher m = pattern.matcher(str); str = m.replaceAll...

    基于Java的市级CMACast资料同步系统的开发.pdf

    - 首先读取配置文件sync.properties,获取需要同步的远程目录和本地目录,并存储在HashMap中。 - 循环HashMap,对比文件名,如果远程服务器有而本地没有的文件,执行时效性检查。 - 通过时效性检查的文件将被下载...

    java最新面试宝典

    - 配置文件(application.properties或application.yml)的编写。 - 自动配置原理。 - **面试考察要点:** - 如何快速搭建Spring Boot应用。 - Spring Boot与传统Spring项目的主要区别。 #### 电商项目 - **知识...

    log4j.rar java写LOG日志的驱动

    2. **配置Log4j**:创建`log4j.properties`或`log4j.xml`配置文件,设置Logger的级别、Appender的类型和Layout的格式。 示例配置: ```properties log4j.rootLogger=DEBUG, stdout, file log4j.appender.stdout...

    jbpm的eclipse的流程设计器插件designer中的gpd.xml文件乱码问题

    5. 使用Eclipse的“Compare with”功能对比正常和乱码的gpd.xml文件,找出差异,可能有助于找出问题的根源。 另外,ui.rar可能是Eclipse Designer的用户界面相关资源,而read me.txt可能是包含解决此类问题或其他...

    JAVA-SSH面试题.doc

    3. **编码转换**:对于非英文资源文件,可能需要进行编码转换,确保正确读取。例如,使用`native2ascii`工具处理中文资源文件,转换编码格式。 通过以上步骤,Struts应用可以根据用户的语言偏好,动态加载相应的...

Global site tag (gtag.js) - Google Analytics