手把手教你实现类似ini4j的方式创建读取和修改.ini文件(支持section)

简介: 手把手教你实现类似ini4j的方式创建读取和修改.ini文件(支持section)

背景



由于这次任务是和c语言合作编写的,刚开始使用ini4j来操作.ini文件,然后由于ini4j对存储的数据做了转义处理,导致c无法正常读取,他们也是采用开源的框架,然后由于java方只有我一个人,势单力薄,这个bug推给了java方来修改,然而时间又比较紧迫,一时之间也找不到合适的jar包,不得不撸起手来自己敲...然后勉强算是解决了bug,性能和安全问题没怎么考虑。


创建.ini文件



/**
 * 创建新的ini文件
 * @param filePath 文件路径
 * @param fileContent 如果要保存存储顺序,建议使用LinkedHashMap
 * @return
 * @throws IOException
 */
public static boolean createIniFile(String filePath, Map<String,Map<String,Object>> fileContent) throws IOException {
    File file = new File(filePath);
    if(file.exists()){
        return false;
    }
    Set<String> keys = null;
    try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file));){
        for (String section : fileContent.keySet()){
            bufferedWriter.write("["+section+"]"+"\r\n");
            keys = fileContent.get(section).keySet();
            for (String key : keys){
                bufferedWriter.write(key+" = "+fileContent.get(section).get(key)+"\r\n");
            }
            bufferedWriter.newLine();
        }
    }catch (Exception e){
        e.printStackTrace();
        throw new IOException("文件写出异常");
    }
    return true;
}
//测试代码
@Test
public void testCreatIniFile(){
    long t2 = System.currentTimeMillis();
    IniUtils.creatIniFile("D:\\abc\\test.ini");
    long t3 = System.currentTimeMillis();
    System.out.println("一:"+(t3-t2));
    Map<String,Map<String,Object>> fileContent = new LinkedHashMap<>();
    fileContent.put("LDAP",new LinkedHashMap<String, Object>(){
        private static final long serialVersionUID = 1L;
        {
            put("ip","1.1.1.1");
            put("port","8569");
            put("pwd","");
            put("user","javac");
        }
    });
    fileContent.put("SAVE",new LinkedHashMap<String, Object>(){
        private static final long serialVersionUID = 1L;
        {
            put("savefiledir","");
            put("savefilesubdir","");
            put("savemode","");
        }
    });
    fileContent.put("LOG",new LinkedHashMap<String, Object>(){
        private static final long serialVersionUID = 1L;
        {
            put("logDebugOpen","");
            put("logFileName","");
        }
    });
    fileContent.put("SEARCH",new LinkedHashMap<String, Object>(){
        private static final long serialVersionUID = 1L;
        {
            put("searchbasedn","");
            put("searchfilter","");
            put("searchflag","");
            put("maxcrls","");
            put("postfix","");
            put("base64check","");
        }
    });
    fileContent.put("SHECA",new LinkedHashMap<String, Object>(){
        private static final long serialVersionUID = 1L;
        {
            put("LibName","");
        }
    });
    fileContent.put("TIMER",new LinkedHashMap<String, Object>(){
        private static final long serialVersionUID = 1L;
        {
            put("timermode","");
            put("timerspan","");
        }
    });
    long t0 = System.currentTimeMillis();
    FileUtils.createIniFile("D:\\abc\\test0.ini",fileContent);
    long t1 = System.currentTimeMillis();
    System.out.println("二:"+(t1-t0));
}


结果如下图(和使用ini4j生成的区别不大,只是没有转义的问题):


查看.ini文件



/**
* 读取文件内容
* @param file 文件
* @return
* @throws IOException
*/
public static Map<String,Map<String,String>> readIniFile(File file) throws IOException {
    //存放所有的数据
    Map<String,Map<String,String>> dataMap = new HashMap<>();
    //存放session下的所有value值
    Map<String,String> paramaters = null;
    try (BufferedReader br = new BufferedReader(new FileReader(file));){
    //读取的行
    String readLine = "";
    //正则
    String regex = "\\[\\w+\\]";
    //存放读取的session
    String session = "";
    //存放key和value值
    String[] map = null;
    while ((readLine = br.readLine()) != null){
    if(null != readLine && !"".equals(readLine)){
        if(readLine.matches(regex)){
            if(null != session && !"".equals(session)){
                dataMap.put(session,paramaters);
            }
            paramaters = new HashMap<>();
            session = readLine.substring(1,readLine.length()-1);
        } else {
            map = readLine.split(" = ");
            paramaters.put(map[0],map.length>1 ? map[1] : "");
        }
    }
            }
            dataMap.put(session,paramaters);
            return dataMap;
        }
    }


测试代码及其输出结果


@Test
public void testReadIniFile(){
    Map<String,Map<String,String>> dataMap = FileUtils.readIniFile(new File("D:\\abc\\test0.ini"));
    dataMap.forEach((k,v)->{
        System.out.println("["+k+"]");
        v.forEach((key,value)->{
            System.out.println(key+" = "+value);
        });
    });
}
//打印结果和图片里的内容是一致的
[LDAP]
port = 8569
ip = 1.1.1.1
pwd = 
user = javac
[LOG]
logFileName = 
logDebugOpen = 
[SEARCH]
searchbasedn = 
searchfilter = 
searchflag = 
postfix = 
base64check = 
maxcrls = 
[TIMER]
timermode = 
timerspan = 
[SAVE]
savemode = 
savefilesubdir = 
savefiledir = 
[SHECA]
LibName = 
Process finished with exit code 0


单行写入



/**
* 修改文件中某个值得属性
* @param filePath 文件路径
* @param section 区块
* @param key 键
* @param value 值
* @return 保存是否成功
* @throws IOException
*/
public static boolean setIniFileString(File file,String section,String key,Object value) throws IOException {
    if(!file.exists()){
        return false;
    }
    String readLine = "";
    StringBuilder sb = new StringBuilder();
    boolean sectionFlag = false;
    boolean changeFlag = false;
    String readKey = "";
    try(BufferedReader bufferedReader = new BufferedReader(new FileReader(file));){
        while ((readLine=bufferedReader.readLine())!=null) {
            if(readLine.trim().equals(section)){
                sectionFlag = true;
            }
            if(readLine.contains("[") && readLine.contains("]")){
                if(!readLine.trim().equals(section)){
                    sectionFlag = false;
                }
            }
            if(sectionFlag && readLine.contains(key)){
                readKey = readLine.substring(0,readLine.indexOf(" "));
                if(readKey.equals(key)){
                    readLine = readKey + " = "+value;
                    changeFlag = true;
                }
            }
            sb.append(readLine+"\r\n");
        }
        if(!changeFlag){
            return false;
        }
    } catch (Exception e){
        throw new IOException("文件读取或写入异常");
    }
    try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file));){
        bufferedWriter.write(sb.toString());
        bufferedWriter.flush();
    }catch (Exception e){
        e.printStackTrace();
    }
    return true;
}


测试代码及结果


@Test
public void test(){
    File file = new File("D:\\abc\\test0.ini");
    FileUtils.setIniFileString(file,"LDAP","ip","8.8.8.8");
    Map<String,Map<String,String>> dataMap = FileUtils.readIniFile(new File("D:\\abc\\test0.ini"));
        dataMap.forEach((k,v)->{
            System.out.println("["+k+"]");
            v.forEach((key,value)->{
                System.out.println(key+" = "+value);
        });
    });  
}
//打印结果
 [LDAP]
port = 8569
ip = 8.8.8.8
pwd = 
user = javac
[LOG]
logFileName = 
logDebugOpen = 
[SEARCH]
searchbasedn = 
searchfilter = 
searchflag = 
postfix = 
base64check = 
maxcrls = 
[TIMER]
timermode = 
timerspan = 
[SAVE]
savemode = 
savefilesubdir = 
savefiledir = 
[SHECA]
LibName = 
Process finished with exit code 0


这个和ini4j相比,有一个差距很大的地方就是写入的时候,一次只能写入一行,而且需要读取源文件,然后比对是否匹配,对上才修改。而Ini4j是可以同时修改一行或多行。目前没有想到什么可行的办法,只能去拜读源码了。日后继续更新!

目录
相关文章
|
4月前
|
存储
Qt使用 QSetting 对 ini 配置文件进行操作
Qt使用 QSetting 对 ini 配置文件进行操作
340 0
|
7月前
|
Linux Shell 开发工具
C++ 的 ini 配置文件读写/注释库 inicpp 用法 [ header-file-only ]
这是一个C++库,名为inicpp,用于读写带有注释的INI配置文件,仅包含一个hpp头文件,无需编译,支持C++11及以上版本。该库提供简单的接口,使得操作INI文件变得容易。用户可通过`git clone`从GitHub或Gitee获取库,并通过包含`inicpp.hpp`来使用`inicpp::iniReader`类。示例代码展示了读取、写入配置项以及添加注释的功能,还提供了转换为字符串、双精度和整型的函数。项目遵循MIT许可证,示例代码可在Linux环境下编译运行。
539 0
|
7月前
使用 gopkg.in/ini.v1 包处理 INI 文件时,你可以使用 Section.HasKey 方法来检查某个 Section 中是否存在指定的 key
使用 gopkg.in/ini.v1 包处理 INI 文件时,你可以使用 Section.HasKey 方法来检查某个 Section 中是否存在指定的 key
|
存储 Java
java使用ini4j读写和修改ini配置文件(支持section)
java使用ini4j读写和修改ini配置文件(支持section)
742 0
java使用ini4j读写和修改ini配置文件(支持section)
|
存储 API 数据格式
Qt通过QSttings类读取*.ini配置文件
Qt通过QSttings类读取*.ini配置文件
224 0
C读取INI的代码实例
C读取INI的代码实例
79 0
|
Go 开发工具
包gopkg.in/ini.v1在 Go 中提供 INI 文件读取和写入功能
包gopkg.in/ini.v1在 Go 中提供 INI 文件读取和写入功能
208 0
MYSQL5的my.ini文件内容(最精简,带注释)
MYSQL5的my.ini文件内容(最精简,带注释)
292 0
|
API
INI文件的写入与读取
INI文件的写入与读取  [节名]         '[]中的节名对应此API的第一参数 Name=内容      'Nmae对应此API的第二参数 API的第三参数是没有取到匹配内容时返回的字符串; API的第四参数是要返回的字符串; API的第五参数是字符串缓冲的长度,一般255; API的第六参数是INI文件的路径。
1418 0