Java的配置文件一般用.properties
,但总有想用.ini
的时候,比如要Java与C#一起用又不想用到占内存的数据库。
这时候先找有没开源库,然后找到org.dtools.javaini-v1.1.1
,这货果然可以读写,不过发现有两点不好的地方:
操作麻烦,读个文件还得写好几行
IniFile iniFile = new BasicIniFile(); IniFileReader reader = new IniFileReader(iniFile, new File(doingDir + "\\" + sno + ".ini")); try { reader.read(); } catch (IOException e) { e.printStackTrace(); }
IniFileWriter
会直接覆盖原文件内容,那我想新增一个key就直接把以前的都写没了。
于是另找,然而并没有找到更好的了。
换个思路,既然C#的读写很方便且我只用在Windows上,于是找个Java调用Windows API的库就好啦,就找到了JNA。
C#读写只需要导入dll即可使用
[DllImport("kernel32")]
private static extern long WritePrivateProfileString(string section,string key,string val,string filePath);
以下是教程:
下载它的jna.jar
和jna-platform.jar
,看文档得知有提供接口和类,Kernel32.INSTANCE
就有读写方法,有更大需要的话可以自己实现Kernel32
接口。
对其封装一下,写方法直接调用即可,不过读方法的缓冲区参数就不像C#那样是String,居然是char[],得根据返回值决定具体大小。
private String iniPath;
private final int bufferSize = 50;
public boolean iniWriteValue(String section, String key, String value) {
return Kernel32.INSTANCE.WritePrivateProfileString(section, key, value, this.iniPath);
}
public String iniReadValue(String section, String key) {
WinDef.DWORD size = new WinDef.DWORD(bufferSize);
char[] temp = new char[bufferSize];
WinDef.DWORD charSize = Kernel32.INSTANCE.GetPrivateProfileString(section, key, "", temp, size,this.iniPath);
return new String(temp,0,charSize.intValue());
}
然后,如果你要放到tomcat
上,那么jna.jar
和jna-platform.jar
除了要添加build path
外还要放到tomcat
的lib
下,不然就跟我一样ClassNotFoundException: com.sun.jna.platform.win32
了。
下面是完整的类,初始化路径后直接调用那2个方法即可。如果想遍历出ini的所有,那有点麻烦,还是直接当普通文本读入就好了。
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.WinDef;
public class Win32Helper {
private String iniPath;
private final int bufferSize = 50;
public Win32Helper() {
}
/**
* Init ini file path
* @param iniPath
*/
public Win32Helper(String iniPath) {
this.iniPath = iniPath;
}
public String getIniPath() {
return iniPath;
}
public void setIniPath(String iniPath) {
this.iniPath = iniPath;
}
/**
*
* @param section
* @param key
* @param value
* @return success or not
*/
public boolean iniWriteValue(String section, String key, String value) {
return Kernel32.INSTANCE.WritePrivateProfileString(section, key, value, this.iniPath);
}
/**
* read a value,it will be error if file not exist,but i haven't throws a exception
* @param section
* @param key
* @return value or ""
*/
public String iniReadValue(String section, String key) {
WinDef.DWORD size = new WinDef.DWORD(bufferSize);
char[] temp = new char[bufferSize];
WinDef.DWORD charSize = Kernel32.INSTANCE.GetPrivateProfileString(section, key, "", temp, size,this.iniPath);
return new String(temp,0,charSize.intValue());
}
}