背景
由于这次任务是和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> fileContent) throws IOException {
File file = new File(filePath);
if(file.exists()){
return false;
}
Set 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;
}//测试代码@Testpublic void testCreatIniFile(){long t2 = System.currentTimeMillis();
IniUtils.creatIniFile("D:\\abc\\test.ini");long t3 = System.currentTimeMillis();
System.out.println("一:"+(t3-t2));
Map> fileContent = new LinkedHashMap<>();
fileContent.put("LDAP",new LinkedHashMap(){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(){private static final long serialVersionUID = 1L;
{
put("savefiledir","");
put("savefilesubdir","");
put("savemode","");
}
});
fileContent.put("LOG",new LinkedHashMap(){private static final long serialVersionUID = 1L;
{
put("logDebugOpen","");
put("logFileName","");
}
});
fileContent.put("SEARCH",new LinkedHashMap(){private static final long serialVersionUID = 1L;
{
put("searchbasedn","");
put("searchfilter","");
put("searchflag","");
put("maxcrls","");
put("postfix","");
put("base64check","");
}
});
fileContent.put("SHECA",new LinkedHashMap(){private static final long serialVersionUID = 1L;
{
put("LibName","");
}
});
fileContent.put("TIMER",new LinkedHashMap(){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> readIniFile(File file) throws IOException {//存放所有的数据
Map> dataMap = new HashMap<>();//存放session下的所有value值
Map 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> 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> 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是可以同时修改一行或多行。目前没有想到什么可行的办法,只能去拜读源码了。日后继续更新!