Java:Properties与配置文件

每个应用程序通常都有与之相匹配的配置文件。例如,一个配置文件的设置:

//上次最后打开的文件:
last_open_file=/data/hello.txt
//自动保存文件的时间间隔
auto_save_interval=60

配置文件的特点是,它的K-V一般都是String-String,所以我们可以用Map<String,String>来表示它。

由于配置文件很常用,所以Java集合库提供了一个Properties来表示一组“配置”Properties本质上是一个HashTable,但我们只需要用到Properties自身关于读写配置接口

模块:java.util.Properties

读取配置文件

Java默认配置文件以.properties为后缀,每行以Key=Value表示,以#开头的是注释

某个典型的配置文件

#setting.properties
last_open_file=/data/hello.txt
auto_save_interval=60

可以从文件系统读取这个.properties文件:

String f = "setting.properties";
Properties pros = new Properties();
props.load(new java.io.FileInputStream(f));

String filepath=props.getProperty("last_open_file");
String interval=props.getProperty("auto_save_interval","120");

所以,从Properties读取配置文件,一共有三步:

  1. 创建Properties实例;
  2. 调用Propertiesload()方法读取配置文件
  3. 嗲用PropertiesgetProperty()获取配置。

调用getProperty()获取配置时,如果Key不存在,会返回null。我们还可以提供一个default,当Key不存在时,返回该default

load()加载.properties时,可以从classpath读取,因为load(InputStream)接收一个InputStream实例,表示一个字节流,不一定是文字流,也可能是从jar包中读取的资源流

Properties props = new Properties();
props.load(getClass().getResourceAsStream("/common/setting.properties"));

 尝试从内存(即一个字符串)中读取一个字节流:

复制代码
import java.io.*;
import java.util.Properties;

public class Main {
    public static void main(String[] args) {
        //定义一个只有2行的K-V

        String settings = "# test" + "\n" + "course=Java" + "\n" +
                "last_open_date=2019-08-07T12:35:01";
        try {
            ByteArrayInputStream input = new ByteArrayInputStream(settings.getBytes("UTF-8"));
            Properties props = new Properties();
            props.load(input);
            System.out.println("course: " + props.getProperty("course"));
            System.out.println("last_open_date: " + props.getProperty("last_open_date"));
            System.out.println("auto_save: " + props.getProperty("auto_save", "60"));
        } catch (UnsupportedEncodingException e) {
            System.out.println(e);
        } catch (IOException e) {
            System.out.println(e);
        }
    }
}
复制代码

执行结果:

course: Java
last_open_date: 2019-08-07T12:35:01
auto_save: 60

由于getBytes()load()分别会抛出UnsupportedEncodingException、IOException,所以必须用try...catch...语句将之捕获。

 

如果有多个.properties文件,可以反复调用load()读取,只是后读取K-V覆盖已读取K-V

Properties props = new Properties();
props.load(getClass().getResourceAsStream("/common/setting.properties"));
props.load(new FileInputStream("C:\\conf\\setting.properties"));

上边的代码演示了Properties的一个常用用法:把默认配置文件放在classpath中,然后根据机器环境编写另一个配置文件,覆盖某些默认配置

Properties设计的目的是存储String类型的K-V,但其实它是从Hashtable派生的,除了getProperty()、setProperty()方法之外,我们不要调用别的从Hashtable继承下来的方法,比如get()、put()

 

写入配置文件

通过setProperty()修改Properties实例,可以把配置写入.properties文件,以便下次启动获得最新配置。写入配置文件使用了store()方法:

Properties props = new Properties();
props.setProperty("url","www.liaoxuefeng.com");
props.setProperty("language","Java");
props.store(new FileOutputStream("C:\\conf\\setting.properties"),"这是写入的properties注释");

编码

早期的.properties文件编码是ASCII;从JDK9开始,可以使用UTF-8编码。

需要注意的是,load( InputStream )默认以ASCII编码读取字节流,所以会导致读到乱码。为了解决这个问题,我们需要用另一个重载方法load( Reader )读取:

Properties props = new Properties();
props.load(new FileReader("settings.properties",StandardCharsets.UTF-8));

就可以正常读取中文InputStreamReader的区别在于,前者是字节流,后者是字符流。字符流在内存中已经以char类型表示了,不涉及编码

 

posted @   ShineLe  阅读(402)  评论(0编辑  收藏  举报
编辑推荐:
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
阅读排行:
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
点击右上角即可分享
微信分享提示