今天总结一篇工具箱文章。

  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 文件操作指南的更多相关文章

  1. C# ini文件操作【源码下载】

    介绍C#如何对ini文件进行读写操作,C#可以通过调用[kernel32.dll]文件中的 WritePrivateProfileString()和GetPrivateProfileString()函 ...

  2. C#读取ini文件的方法

    最近项目用到ini文件,读取ini文件,方法如下: using System; using System.Collections.Generic; using System.Linq; using S ...

  3. IIS不能下载ini文件

    1.打开IIS. 2.选择站点或者存放*.ini文件的目录,右键菜单中选择属性. 3.选择“HTTP头”选项卡. 4.点击“MINE类型”. 5.点击“新建”. 6.这是跳出一个对话框,在“扩展名”一 ...

  4. c# 利用动态库DllImport("kernel32")读写ini文件(提供Dmo下载)

    c# 利用动态库DllImport("kernel32")读写ini文件 自从读了设计模式,真的会改变一个程序员的习惯.我觉得嘛,经验也可以从一个人的习惯看得出来,看他的代码编写习 ...

  5. 伪静态重写模块rewrite.dll及httpd.ini文件参考下载

    伪静态重写模块rewrite.dll及httpd.ini文件参考下载 http://www.ledaokj.com/download/rewrite.rar 服务器端开启伪静态,可以查看以下文章< ...

  6. c#读取INI文件

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.I ...

  7. 创建Unicode格式的INI文件

    前段时间由于开发一个软件,需要调用别人的接口,虽然我的软件是Unicode编码,对方的模块也是Unicode编码,但是对方提供的接口却是Ansi接口,在非中文系统下,由于涉及到中文路径,导致Ansi和 ...

  8. 【vbs】vbs写ini文件

    这两天在折腾给一个项目打安装包,第一次接触软件打包,用的Advanced Installer(以下简称AI),应该说如果安装过程没有特殊动作(常规动作指释放文件.写注册表.建快捷方式等)的话,倒挺傻瓜 ...

  9. ini文件操作

    Config.ini 文件操作 [SYS] sysname=hy company=hyhy tel=2 using System; using System.Collections.Generic; ...

随机推荐

  1. 关于BFC的一些事

    BFC的生成 在实现CSS的布局时,假设我们不知道BFC的话,很多地方我们生成了BFC但是不知道.在布局中,一个元素是block元素还是inline元素是必须要知道的.而BFC就是用来格式化块状元素盒 ...

  2. getMeasuredHeight()与getHeight() 以及MeasureSpec.getSize()

    getMeasuredHeight()返回的是原始测量高度,与屏幕无关,getHeight()返回的是在屏幕上显示的高度.实际上在当屏幕可以包裹内容的时候,他们的值是相等的,只有当view超出屏幕后, ...

  3. 【第十五篇】easyui datagrid的列编辑,同时插入两张表的数据进去

    看图说话. 需求:插入两张表,上面的表单是第一张表的内容,下面的两个表格是第二张详情表的内容,跟第一张表的id关联 第二张表有一个列是需要用户手动填写添加的. 国际惯例,上代码 <div id= ...

  4. Java高性能编程之CAS与ABA及解决方法

    Java高性能编程之CAS与ABA及解决方法 前言 如果喜欢暗色调的界面或者想换换界面,可以看看我在个人博客发布的 Java高性能编程之CAS与ABA及解决方法. CAS概念 CAS,全称Compar ...

  5. Docker入门到实践——简单操作

    1.对比传统虚拟机总结 特性 容器 虚拟机 启动 秒级 分钟级 硬盘使用 一般为MB 一般为GB 性能 接近原生 弱于 系统支持量 单机支持上千个容器 一般几十个 2.基本概念 Docker包括三个基 ...

  6. IBM DB2 SQL error code list

    SQL return codes that are preceded by a minus sign (-) indicate that the SQL statement execution was ...

  7. 使用 Docker 安装 showdoc

    一.简介 ShowDoc 是一个非常适合IT团队在线共享文档的工具,在线访问地址为:https://www.showDoc.cc 本来也可以直接 pull showdoc 镜像到本地,使用 docke ...

  8. Linux MySQL-5.7 root初始密码修改

    操作系统为centos7 64 1.修改 /etc/my.cnf,在 [mysqld] 小节下添加一行:skip-grant-tables=1 这一行配置让 mysqld 启动时不对密码进行验证 2. ...

  9. React学习笔记(持续更新)

    2.2页面加载过程 1.资源加载过程:URL->DNS查询->资源请求->浏览器解析 ①URL结构:http://www.hhh.com:80/getdata?pid=1#title ...

  10. UITableView tableHeaderView 自动布局

    let size = headerView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize) headerView.frame.s ...