Java读取properties配置文件的8种方式汇总
作者:Thinkingcao 发布时间:2022-05-03 17:11:34
一、前言
在做Java
项目开发过程中,涉及到一些数据库服务连接配置、缓存服务器连接配置等,通常情况下我们会将这些不太变动的配置信息存储在以 .properties
结尾的配置文件中。当对应的服务器地址或者账号密码信息有所变动时,我们只需要修改一下配置文件中的信息即可。同时为了让Java
程序可以读取 .properties
配置文件中的值,Java
的JDK
中提供了java.util.Properties
类可以实现读取配置文件。
二、Properties类
Properties 类位于 java.util.Properties中,是Java 语言的处理配置文件所使用的类,其中的xxx.Properties
类主要用于集中的持久存储Java
的配置文件内容,可以读取后缀是.properties
和.cfg
的配置文件。
Properties继承了Hashtable 类,以Map 的形式进行放置值,put(key,value)
和 get(key)
,文本注释信息可以用"#"来注释。
Properties 类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串。
Properties 文件内容的格式是:键=值 形式,Key值不能够重复。 例如:
jdbc.driver=com.mysql.jdbc.Driver
Properties类的继承关系图:
Properties类的源码关系图:
主要方法介绍:
它提供了几个核心的方法:
getProperty ( String key): 用指定的键在此属性列表中搜索属性。也就是通过参数 key ,得到 key 所对应的 value。
load ( InputStream inStream): 从输入流中读取属性列表(键和元素对)。通过对指定的文件(比如说上面的 test.properties 文件)进行装载来获取该文件中的所有键 - 值对。以供 getProperty ( String key) 来搜索。
setProperty ( String key, String value) : 调用 Hashtable 的方法 put 。他通过调用基类的put方法来设置 键 - 值对。
store ( OutputStream out, String comments): 以适合使用 load 方法加载到 Properties 表中的格式,将此 Properties 表中的属性列表(键和元素对)写入输出流。与 load 方法相反,该方法将键 - 值对写入到指定的文件中去。
clear (): 清除所有装载的 键 - 值对。该方法在基类中提供。
三、Properties常用方法实践
Properties
类我们从文件的写入和读取来实践其具体用法,下面演示练习将以下数据库配置信息写入到jdbc.properties
文件中
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf8
jdbc.username=root
jdbc.password=123456
项目目录结构如下
四、Java写入Properties
Properties类调用setProperty方法将键值对保存到内存中,此时可以通过getProperty方法读取,propertyNames方法进行遍历,但是并没有将键值对持久化到属性文件中,故需要调用store方法持久化键值对到属性文件中。
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Properties;
/**
* @desc: 写入Mysql数据库了连接信息到jdbc.properties中
* @author: cao_wencao
* @date: 2020-12-29 13:41
*/
public class PropertiesStoreTest {
public static void main(String[] args) {
Properties properties = new Properties();
OutputStream output = null;
try {
output = new FileOutputStream("src/main/resources/jdbc.properties");
properties.setProperty("jdbc.driver", "com.mysql.jdbc.Driver");
properties.setProperty("jdbc.url","jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf8" );
properties.setProperty("jdbc.username", "root");
properties.setProperty("jdbc.password", "123456");
// 保存键值对到文件中
properties.store(output, "Thinkingcao modify");
} catch (IOException io) {
io.printStackTrace();
} finally {
if (output != null) {
try {
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
输出结果,在resources目录下多一个文件jdbc.properties,内容如下:
#Thinkingcao modify
#Tue Dec 29 13:43:48 CST 2020
jdbc.url=jdbc\:mysql\://localhost\:3306/mybatis?characterEncoding\=utf8
jdbc.username=root
jdbc.driver=com.mysql.jdbc.Driver
jdbc.password=123456
五、Java读取Properties
Java读取Properties文件的方法有很多,下面介绍8种方式,分别读取resource目录下的jdbc.properties和resource/config/application.properties。
application.properties文件内容如下
minio.endpoint=http://localhost:9000
minio.accessKey=minioadmin
minio.secretKey=minioadmin
minio.bucketName=demo
1. 从当前的类加载器的getResourcesAsStream来获取
/**
* 1. 方式一
* 从当前的类加载器的getResourcesAsStream来获取
* InputStream inputStream = this.getClass().getResourceAsStream(name)
*
* @throws IOException
*/
@Test
public void test1() throws IOException {
InputStream inputStream = this.getClass().getResourceAsStream("jdbc.properties");
Properties properties = new Properties();
properties.load(inputStream);
properties.list(System.out);
System.out.println("==============================================");
String property = properties.getProperty("jdbc.url");
System.out.println("property = " + property);
}
2. 从当前的类加载器的getClassLoader().getResourcesAsStream来获取
/**
* 2. 方式二
* 从当前的类加载器的getResourcesAsStream来获取
* InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(name)
*
* @throws IOException
*/
@Test
public void test2() throws IOException {
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("config/application.properties");
Properties properties = new Properties();
properties.load(inputStream);
properties.list(System.out);
System.out.println("==============================================");
String property = properties.getProperty("minio.endpoint");
System.out.println("property = " + property);
}
3. 使用Class类的getSystemResourceAsStream静态方法 和使用当前类的ClassLoader是一样的
/**
* 3. 方式三
* 使用Class类的getSystemResourceAsStream方法 和使用当前类的ClassLoader是一样的
* InputStream inputStream = ClassLoader.getSystemResourceAsStream(name)
*
* @throws IOException
*/
@Test
public void test3() throws IOException {
InputStream inputStream = ClassLoader.getSystemResourceAsStream("config/application.properties");
Properties properties = new Properties();
properties.load(inputStream);
properties.list(System.out);
System.out.println("==============================================");
String property = properties.getProperty("minio.endpoint");
System.out.println("property = " + property);
}
4. 使用Spring-core包中的ClassPathResource读取
/**
* 4. 方式四
* Resource resource = new ClassPathResource(path)
*
* @throws IOException
*/
@Test
public void test4() throws IOException {
Resource resource = new ClassPathResource("config/application.properties");
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
properties.list(System.out);
System.out.println("==============================================");
String property = properties.getProperty("minio.endpoint");
System.out.println("property = " + property);
}
5. 从文件中读取,new BufferedInputStream(InputStream in)
/**
* 5. 方式五
* 从文件中获取,使用InputStream字节,主要是需要加上当前配置文件所在的项目src目录地址。路径配置需要精确到绝对地址级别
* BufferedInputStream继承自InputStream
* InputStream inputStream = new BufferedInputStream(new FileInputStream(name)
* 这种方法读取需要完整的路径,优点是可以读取任意路径下的文件,缺点是不太灵活
* @throws IOException
*/
@Test
public void test5() throws IOException {
InputStream inputStream = new BufferedInputStream(new FileInputStream("src/main/resources/config/application.properties"));
Properties properties = new Properties();
properties.load(inputStream);
properties.list(System.out);
System.out.println("==============================================");
String property = properties.getProperty("minio.endpoint");
System.out.println("property = " + property);
}
6.从文件中读取,new FileInputStream(String name)
/**
* 6. 方式六
* 从文件中获取,使用InputStream字节,主要是需要加上当前配置文件所在的项目src目录地址。路径配置需要精确到绝对地址级别
* FileInputStream继承自InputStream
* InputStream inputStream = new FileInputStream(name)
* 这种方法读取需要完整的路径,优点是可以读取任意路径下的文件,缺点是不太灵活
* @throws IOException
*/
@Test
public void test6() throws IOException {
InputStream inputStream = new FileInputStream("src/main/resources/config/application.properties");
Properties properties = new Properties();
properties.load(inputStream);
properties.list(System.out);
System.out.println("==============================================");
String property = properties.getProperty("minio.endpoint");
System.out.println("property = " + property);
}
7. 使用PropertyResourceBundle读取InputStream流
/**
* 7. 方式七
* 使用InputStream流来进行操作ResourceBundle,获取流的方式由以上几种。
* ResourceBundle resourceBundle = new PropertyResourceBundle(inputStream);
* @throws IOException
*/
@Test
public void test7() throws IOException {
InputStream inputStream = ClassLoader.getSystemResourceAsStream("config/application.properties");
ResourceBundle resourceBundle = new PropertyResourceBundle(inputStream);
Enumeration<String> keys = resourceBundle.getKeys();
while (keys.hasMoreElements()) {
String s = keys.nextElement();
System.out.println(s + " = " + resourceBundle.getString(s));
}
}
8. 使用ResourceBundle.getBundle读取
/**
* 8. 方式八
* ResourceBundle.getBundle的路径访问和 Class.getClassLoader.getResourceAsStream类似,默认从根目录下读取,也可以读取resources目录下的文件
* ResourceBundle rb = ResourceBundle.getBundle("b") //不需要指定文件名的后缀,只需要写文件名前缀即可
*/
@Test
public void test8(){
//ResourceBundle rb = ResourceBundle.getBundle("jdbc"); //读取resources目录下的jdbc.properties
ResourceBundle rb2 = ResourceBundle.getBundle("config/application");//读取resources/config目录下的application.properties
for(String key : rb2.keySet()){
String value = rb2.getString(key);
System.out.println(key + ":" + value);
}
}
输出结果:
minio.endpoint:http://localhost:9000
minio.bucketName:demo
minio.secretKey:minioadmin
minio.accessKey:minioadmin
六、Properties配合Spring框架使用
加载.properties方式一
<!-- 1.加载 jdbc.properties 配置文件 -->
<context:property-placeholder location="classpath:jdbc.properties" system-properties-mode="NEVER"/>
除了上面这种方式之外,还有下面这种List集合的方式
加载.properties方式二
<!-- 4.引入外部配置文件 由于后期可能会引入多个配置文件 所以采用list的形式 -->
<bean id="propertyPlaceholder"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:/config/jdbc.properties</value>
<value>classpath:/config/application.properties</value>
</list>
</property>
</bean>
七、完整代码
import org.junit.Test;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
/**
* @desc: Properties读取配置文件属性值的方式
* @author: cao_wencao
* @date: 2020-12-29 10:08
*/
public class PropertiesTest {
/**
* 1. 方式一
* 从当前的类加载器的getResourcesAsStream来获取
* InputStream inputStream = this.getClass().getResourceAsStream(name)
*
* @throws IOException
*/
@Test
public void test1() throws IOException {
InputStream inputStream = this.getClass().getResourceAsStream("jdbc.properties");
Properties properties = new Properties();
properties.load(inputStream);
properties.list(System.out);
System.out.println("==============================================");
String property = properties.getProperty("jdbc.url");
System.out.println("property = " + property);
}
/**
* 2. 方式二
* 从当前的类加载器的getResourcesAsStream来获取
* InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(name)
*
* @throws IOException
*/
@Test
public void test5() throws IOException {
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("config/application.properties");
Properties properties = new Properties();
properties.load(inputStream);
properties.list(System.out);
System.out.println("==============================================");
String property = properties.getProperty("minio.endpoint");
System.out.println("property = " + property);
}
/**
* 3. 方式三
* 使用Class类的getSystemResourceAsStream方法 和使用当前类的ClassLoader是一样的
* InputStream inputStream = ClassLoader.getSystemResourceAsStream(name)
*
* @throws IOException
*/
@Test
public void test4() throws IOException {
InputStream inputStream = ClassLoader.getSystemResourceAsStream("config/application.properties");
Properties properties = new Properties();
properties.load(inputStream);
properties.list(System.out);
System.out.println("==============================================");
String property = properties.getProperty("minio.endpoint");
System.out.println("property = " + property);
}
/**
* 4. 方式四
* Resource resource = new ClassPathResource(path)
*
* @throws IOException
*/
@Test
public void test2() throws IOException {
Resource resource = new ClassPathResource("config/application.properties");
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
properties.list(System.out);
System.out.println("==============================================");
String property = properties.getProperty("minio.endpoint");
System.out.println("property = " + property);
}
/**
* 5. 方式五
* 从文件中获取,使用InputStream字节,主要是需要加上当前配置文件所在的项目src目录地址。路径配置需要精确到绝对地址级别
* BufferedInputStream继承自InputStream
* InputStream inputStream = new BufferedInputStream(new FileInputStream(name)
* 这种方法读取需要完整的路径,优点是可以读取任意路径下的文件,缺点是不太灵活
* @throws IOException
*/
@Test
public void test3() throws IOException {
InputStream inputStream = new BufferedInputStream(new FileInputStream("src/main/resources/config/application.properties"));
Properties properties = new Properties();
properties.load(inputStream);
properties.list(System.out);
System.out.println("==============================================");
String property = properties.getProperty("minio.endpoint");
System.out.println("property = " + property);
}
/**
* 6. 方式六
* 从文件中获取,使用InputStream字节,主要是需要加上当前配置文件所在的项目src目录地址。路径配置需要精确到绝对地址级别
* FileInputStream继承自InputStream
* InputStream inputStream = new FileInputStream(name)
* 这种方法读取需要完整的路径,优点是可以读取任意路径下的文件,缺点是不太灵活
* @throws IOException
*/
@Test
public void test6() throws IOException {
InputStream inputStream = new FileInputStream("src/main/resources/config/application.properties");
Properties properties = new Properties();
properties.load(inputStream);
properties.list(System.out);
System.out.println("==============================================");
String property = properties.getProperty("minio.endpoint");
System.out.println("property = " + property);
}
/**
* 7. 方式七
* 使用InputStream流来进行操作ResourceBundle,获取流的方式由以上几种。
* ResourceBundle resourceBundle = new PropertyResourceBundle(inputStream);
* @throws IOException
*/
@Test
public void test7() throws IOException {
InputStream inputStream = ClassLoader.getSystemResourceAsStream("config/application.properties");
ResourceBundle resourceBundle = new PropertyResourceBundle(inputStream);
Enumeration<String> keys = resourceBundle.getKeys();
while (keys.hasMoreElements()) {
String s = keys.nextElement();
System.out.println(s + " = " + resourceBundle.getString(s));
}
}
/**
* 8. 方式八
* ResourceBundle.getBundle的路径访问和 Class.getClassLoader.getResourceAsStream类似,默认从根目录下读取,也可以读取resources目录下的文件
* ResourceBundle rb = ResourceBundle.getBundle("b") //不需要指定文件名的后缀,只需要写文件名前缀即可
*/
@Test
public void test8(){
//ResourceBundle rb = ResourceBundle.getBundle("jdbc"); //读取resources目录下的jdbc.properties
ResourceBundle rb2 = ResourceBundle.getBundle("config/application");//读取resources/config目录下的application.properties
for(String key : rb2.keySet()){
String value = rb2.getString(key);
System.out.println(key + ":" + value);
}
}
/**
* 单独抽取的方法,用户检测能否正确操纵Properties
*
* @param inputStream
* @throws IOException
*/
private void printKeyValue(InputStream inputStream) throws IOException {
Properties properties = new Properties();
properties.load(inputStream);
Set<Object> keys = properties.keySet();
for (Object key : keys) {
System.out.println(key + " = " + properties.get(key));
}
}
}
来源:https://blog.csdn.net/Thinkingcao/article/details/111897862


猜你喜欢
- 本文实例讲述了Java求解两个非负整数最大公约数算法。分享给大家供大家参考,具体如下:代码功能:1.Java实现(完整源码附测试用例);2.
- 1.首先,需要指定获取的文件夹,以及获取文件的文件名;文件夹:strLocalPath = System.Windows.Forms.App
- Spring如何使用 * 缓存解决循环依赖在没开始文章之前首先来了解一下什么是循环依赖@Componentpublic class A {@A
- 本文实例讲述了Android编程使WebView支持HTML5 Video全屏播放的解决方法。分享给大家供大家参考,具体如下:1)需要在An
- 一.介绍门面模式(Facade Pattern)属于结构型模式。门面模式又叫作外观模式,通过给多个复杂的子系统提供一个门面(高层接口),使这
- 前言在做项目的时候,遇到一个需求,需要我对Chart图标标记数据正在运行,实现数据可视化,因为我们的表格是隐藏Y轴的刻度是看不到数据值的,于
- 在网上找了半天,说的都没有解决我的问题,我自己花了点时间在idea中找到并解决了问题,希望可以帮助到大家。File---->setti
- 这篇文章主要介绍了springboot @Configuration @bean注解作用解析,文中通过示例代码介绍的非常详细,对大家的学习或
- 1.类的属性 filed1)在kotlin中定义属性,必须赋初始值,要不编译器检查不通过。这个和java不同2)kotlin会针对于定义的每
- 本文实例讲述了Java代理模式。分享给大家供大家参考,具体如下:即Proxy Pattern,23种java常用设计模式之一。代理模式的定义
- Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。 1.方法声明时使
- 实践过程效果代码public partial class FrmGetColor : Form{ public F
- 概念装饰者模式动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。装饰者和被装饰对象有相同的超类型。你可以用一个或
- Message的创建消息Message一般不支持大家直接通过new的方式进行创建的,因为Message作为Android系统中使用频率非常高
- 关于Retrofit的学习,我算是比较晚的了,而现在Retrofit已经是Android非常流行的网络请求框架了。之前,我没有学过Retro
- 需求:传入多个 id 查询用户信息,用下边两个 sql 实现:SELECT * FROM USERS WHERE username LIKE
- 前言PowerManagerService之亮屏流程分析 分析了亮屏的流程,并归纳出了一个适用于亮屏或灭屏的通用的流程。 但是,灭屏流程还有
- 本文实例介绍了sdcard存储图片下载简单操作,分享给大家供大家参考,具体内容如下步骤 -- 在配置清单添加完联网权限后1、res/layo
- java中初始化MediaRecorder实现代码:private boolean initializeVideo() { &
- 前一段时间遇到一个问题,是关于读取项目中文件资源的问题。我是一个maven工程 我把一张照片放到resource下面,然后在本地读取的时候可