背景
由于这次任务是和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是可以同时修改一行或多行。目前没有想到什么可行的办法,只能去拜读源码了。日后继续更新!