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读取配置文件,一共有三步:
- 创建Properties实例;
- 调用Properties的load()方法读取配置文件;
- 嗲用Properties的getProperty()获取配置。
调用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));
就可以正常读取中文。InputStream和Reader的区别在于,前者是字节流,后者是字符流。字符流在内存中已经以char类型表示了,不涉及编码。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性