ini 文件操作指南
今天总结一篇工具箱文章。
ini 类型文件通常作为程序的初始化文件。不同于我们常见的配置文件通篇 key-value 的键值对形式,ini 文件在键值对的基础之上还有分类节点,比如我们常见的 Mysql 数据库的初始化配置文件 my.cnf或my.ini,其内容格式通常是如下这样的:
[client]
port = 3306
socket = /data/3306/mysql.sock [mysqld]
user = mysql
port = 3306
socket = /data/3306/mysql.sock
basedir = /usr/local/mysql
datadir = /data/3306/data
对于这种格式的文件的读取操作,Java中常用 Properties 类是不太好使的。当然,你也可以自己凭着高超的撸码水平去手写工具方法进行读写操作,但肯定还是比较费神的。实际上我们有第三方工具类库可供选择。此处博主分享的类库叫 org.dtools.javaini。整个工具包很轻便,能够支持基本的读写,格式校验等,官方教程很详细,花很少的时间就能上手。当然,结合项目的使用情况,自己还是需要自己进一步封装些方法以便更好的使用。前人种树,后人乘凉,博主也抛转引玉的写了几个:
package module.ini; import com.alibaba.fastjson.JSONObject;
import org.dtools.ini.*;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.Set; /**
* @date: 2019/10/16 19:11
* @author: chen
* @desc: org.dtools.javaini-v1.1.00.jar 工具包读写ini 文件工具类
*/
public class IniUtil { // ini 文件抽象表示
private static IniFile iniFile = null;
// 要操作的文件实例
private static File file = null; // 操作 ini 文件的阅读器和书写器,通过它们来进行具体的读和写操作
private IniFileReader iniFileReader = null;
private IniFileWriter iniFileWriter = null; /**
* @param filePath 文件路径
* @param caseSensitive 是否区分大小写 默认false
* @param validator 格式校验器
*/
public IniUtil(String filePath, IniValidator validator, boolean caseSensitive) {
file = new File(filePath);
iniFile = new BasicIniFile(validator, caseSensitive);
try {
init();
} catch (IOException e) {
e.printStackTrace();
}
} public IniUtil(String filePath) {
this(filePath, new IniValidator(), false);
} public IniUtil(String filePath, IniValidator validator) {
this(filePath, validator, false);
} public IniUtil(String filePath, boolean caseSensitive) {
this(filePath, new IniValidator(), caseSensitive);
} /**
* 初始化 ini 文件的阅读器和书写器
*/
private void init() throws IOException {
iniFileReader = new IniFileReader(iniFile, file);
iniFileWriter = new IniFileWriter(iniFile, file);
iniFileReader.read();
} /**
* 读取 ini 文件转换数据为 Json对象
*/
public JSONObject getIniFileInfo() {
Iterator<IniSection> sectionIterator = iniFile.iterator();
JSONObject jsonObject = new JSONObject();
while (sectionIterator.hasNext()) {
IniSection section = sectionIterator.next();
Iterator<IniItem> itemIterator = section.iterator();
JSONObject child = new JSONObject();
while (itemIterator.hasNext()) {
IniItem item = itemIterator.next();
child.put(item.getName(), item.getValue());
}
jsonObject.put(section.getName(), child);
}
return jsonObject;
} /**
* 获取某个节点下的所有键值对
*/
public JSONObject getIniBySection(String sectionName) throws Exception {
IniSection section = getSection(sectionName);
Iterator<IniItem> iterator = section.iterator();
JSONObject jsonObject = new JSONObject();
while (iterator.hasNext()) {
IniItem item = iterator.next();
jsonObject.put(item.getName(), item.getValue());
}
return jsonObject;
} /**
* 获取某个节点下某个条目的值
*/
public Object getItemByName(String sectionName, String itemName) throws Exception {
JSONObject iniBySection = this.getIniBySection(sectionName);
return iniBySection.get(itemName);
} /**
* 新增或修改某节点条目
*/
public void addOrUpdateItem(String sectionName, String itemName, String itemValue) throws Exception {
IniSection section = getSection(sectionName);
IniItem iniItem = section.addItem(itemName);
if (iniItem == null)
iniItem = section.getItem(itemName);
iniItem.setValue(itemValue);
iniFileWriter.write();
} /**
* 新增或修改某节点条目 可添加注释
*/
public void addOrUpdateItem(String sectionName, String itemName, String itemValue,String comment) throws Exception {
IniSection section = getSection(sectionName);
IniItem iniItem = section.addItem(itemName);
if (iniItem == null)
iniItem = section.getItem(itemName);
iniItem.setValue(itemValue);
iniItem.setPreComment(comment); // 添加前置注释
iniFileWriter.write();
} /**
* 新增或修改某节点条目
*/
public void addOrUpdateItems(String sectionName, Map<String, Object> itemMap) throws Exception {
IniSection section = iniFile.getSection(sectionName);
Set<String> items = itemMap.keySet();
section.addItems(items.toArray(new String[0]));
iniFileWriter.write();
} /**
* 新增节点
*/
public void addSection(String sectionName) throws IOException {
if (iniFile.addSection(sectionName) == null)
return;
iniFileWriter.write();
} /**
* 删除 某节点
*/
public void removeSection(String sectionName) throws IOException {
if (iniFile.removeSection(sectionName) == null)
return;
iniFileWriter.write();
} /**
* 删除 某条目
*/
public void removeItem(String sectionName, String itemName) throws Exception {
IniSection section = getSection(sectionName);
section.removeItem(itemName);
iniFileWriter.write();
} private IniSection getSection(String sectionName) throws Exception {
if (!iniFile.hasSection(sectionName)) {
throw new Exception("The ini file【" + file.getName() + "】 has no section named " + sectionName);
}
return iniFile.getSection(sectionName);
} }
作为一个比较简单的工具包,应对 ini 类型文件基本的增删改查足够了。如果你要深度使用,还有些问题需要你自己来解决——
① 工具包中对文件默认采用 ASCII 编码,所以对ASCII 码之外的字符比如中文字符就无法支持,如果读写过程中出现中文将会乱码;
② 对注释的支持也不足够。常见的注释为 #,但是作者却只给了以 ; 和 // 号开头的注释,,如果原文件有 # 类型的注释,读写操作后会被清理掉;
由于类库中并没有提供设置编码或注释标注的方法,所以,比较好的办法就是自己下载源码,在源码上进行改动,然后自己打包到自己的项目中使用。以下是博主对代码的改动经验——
首先,对于字符的问题,作者是在 IniFIleWriter 类中定义了一个表示字符的常量,去掉 final 修饰符,便于使用过程中动态修改编码:

其次,对于注释,作者在 Commentable 接口中定义了表示注释开头的 ‘;’ 标识,由于是声明在接口中,默认就是static final 的,所以要改成动态设置的比较难办,改动会比较多,比较好的实践也是最简单粗暴的方式——直接改成通常的 # 注释符就可以了:

最后,重新打成 jar 放入你的项目中或放入你的 maven 仓库。好了,工具方法,就长话短说了,祝使用愉快。
如有什么问题或错漏,欢迎留言交流,不胜感激!
ini 文件操作指南的更多相关文章
- C# ini文件操作【源码下载】
介绍C#如何对ini文件进行读写操作,C#可以通过调用[kernel32.dll]文件中的 WritePrivateProfileString()和GetPrivateProfileString()函 ...
- C#读取ini文件的方法
最近项目用到ini文件,读取ini文件,方法如下: using System; using System.Collections.Generic; using System.Linq; using S ...
- IIS不能下载ini文件
1.打开IIS. 2.选择站点或者存放*.ini文件的目录,右键菜单中选择属性. 3.选择“HTTP头”选项卡. 4.点击“MINE类型”. 5.点击“新建”. 6.这是跳出一个对话框,在“扩展名”一 ...
- c# 利用动态库DllImport("kernel32")读写ini文件(提供Dmo下载)
c# 利用动态库DllImport("kernel32")读写ini文件 自从读了设计模式,真的会改变一个程序员的习惯.我觉得嘛,经验也可以从一个人的习惯看得出来,看他的代码编写习 ...
- 伪静态重写模块rewrite.dll及httpd.ini文件参考下载
伪静态重写模块rewrite.dll及httpd.ini文件参考下载 http://www.ledaokj.com/download/rewrite.rar 服务器端开启伪静态,可以查看以下文章< ...
- c#读取INI文件
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.I ...
- 创建Unicode格式的INI文件
前段时间由于开发一个软件,需要调用别人的接口,虽然我的软件是Unicode编码,对方的模块也是Unicode编码,但是对方提供的接口却是Ansi接口,在非中文系统下,由于涉及到中文路径,导致Ansi和 ...
- 【vbs】vbs写ini文件
这两天在折腾给一个项目打安装包,第一次接触软件打包,用的Advanced Installer(以下简称AI),应该说如果安装过程没有特殊动作(常规动作指释放文件.写注册表.建快捷方式等)的话,倒挺傻瓜 ...
- ini文件操作
Config.ini 文件操作 [SYS] sysname=hy company=hyhy tel=2 using System; using System.Collections.Generic; ...
随机推荐
- Fire Balls 09——修正游戏的BUG
版权申明: 本文原创首发于以下网站: 博客园『优梦创客』的空间:https://www.cnblogs.com/raymondking123 优梦创客的官方博客:https://91make.top ...
- Oracle 11g Rac 用rman实现把本地数据文件迁移到ASM共享存储中
在Oracle Rac环境中,数据文件都是要存放在ASM共享存储上的,这样两个节点才能同时访问.而当你在某一节点下把数据文件创建在本地磁盘的时候,那么在另一节点上要访问该数据文件的时候就会报错,因为找 ...
- 一篇RPO漏洞挖掘文章翻译加深理解。
这是我第一次尝试翻译一篇漏洞挖掘文章,翻译它也是为了加深理解它.这是一篇很有意思的漏洞挖掘文章. 前几天在看fd的博客,偶然看到了这篇文章,虽然有点老了.但是思路真的牛皮.我决定花费时间和精力研究它们 ...
- DDD领域驱动实践记录
虽然很早之前就已经了解过DDD相关的内容了,但一方面网上理论知识太过碎片化导致难以理解,另一方面实践内容太少导致想动手的时候无从下手.于是就渐渐淡忘了这方面实践的念头. 最近重新了解了DDD相关的知识 ...
- springboot数据库主从方案
本篇分享数据库主从方案,案例采用springboot+mysql+mybatis演示:要想在代码中做主从选择,通常需要明白什么时候切换数据源,怎么切换数据源,下面以代码示例来做阐述: 搭建测试环境(1 ...
- 美团集群调度系统HULK技术演进
本文根据美团基础架构部/弹性策略团队负责人涂扬在2019 QCon(全球软件开发大会)上的演讲内容整理而成.本文涉及Kubernetes集群管理技术,美团相关的技术实践可参考此前发布的<美团点评 ...
- 大数据平台搭建 - cdh5.11.1 - hive客户端安装
一.简介 hive是基于hadoop的一种数据仓库工具,可以将结构化的文件映射成为数据库的一张表,并提供简单sql查询功能,底层实现是转化为MapReduce任务计算. 二.安装 (1)下载 从cdh ...
- sql注入(从入门到进阶)
随着B/S模式应用开发的发展,使用这种模式编写应用程序的程序员也越来越多.但是由于这个行业的入门门槛不高,程序员的水平及经验也参差不齐,相当大一部分程序员在编写代码的时候,没有对用户输入数据的合法性进 ...
- SSM整合activiti框架
一:WorkFlow简介 1:什么是工作流工作流(Workflow),指“业务过程的部分或整体在计算机应用环境下的自动化”.是对工作流程及其各操作步骤之间业务规则的抽象.概括描述.在计算机中,工作流属 ...
- 【JVM学习】2.Java虚拟机运行时数据区
来源: 公众号: 猿人谷 这里我们先说句题外话,相信大家在面试中经常被问到介绍Java内存模型,我在面试别人时也会经常问这个问题.但是,往往都会令我比较尴尬,我还话音未落,面试者就会"背诵& ...