作者:Verdlin
翻译:河许人
我对这个库的讨论和留言进行了整合,翻译过程肯定有些瑕疵,请多包涵!谢谢!
ini文件操作是中大型程序几乎必备的操作,但是AHK自带的ini操作太low,所有其他Ini库(包括旧版本的EasyIni)语法又太麻烦。这个类的重点是使读写ini文件尽可能容易;此外,我想让这个类本身易于阅读和其他开发人员的访问。
这个类的一个意想不到的积极结果是它的执行速度比写操作要快得多。我在下面发布了一个示例,在这里,easyini类的速度比IniWrite快1162%。
您可以轻松地使用easyini对象与ini进行交互。由于自定义对象,该类允许您使用熟悉的、本机的、对象语法。
; 创建一个 ini 类 vIni := class_EasyIni("MyIni.ini") ; 与对象进行交互 for section, aKeysAndVals in vIni for key, val in aKeysInVals vIni[Section][key] := 1 vIni[VariableWithSectionName][VariableWithKeyName] := val ; 这通常是在循环遍历各部分和键时使用的 vIni.NameOfSection.NameOfKey := val ; 这种语法是最简单的,但是您必须知道文字部分的名称和键名。 ; 它特别适用于在您的应用程序中处理用户定义的ini变量。 vIni.NameOfSection[VariableWithKeyName] := val ; 这是当你知道文字部分的名字时 vIni[VariableWithSectionName].key := val ; 这是当你知道文字键名的时候
这个类的限制:
- 在段名中不能使用换行符。
- 对于任何字母数字段,(例如:“[A]”)只有一种情况是允许的。因此,如果您试图添加“[a]”“AddSection”()函数将失效。在我的1500个段示例中演示。
- 在我的测试中,我注意到SOH(chr(1))和空格(chr(32))被写入了相同SOH。我不知道为什么会这样,但我不认为这对大多数人来说是一个问题。
- 我还注意到,相当多的奇怪字符值被分组到相同的部分中。这对任何人来说不是一个问题。这个类只是一个奇特的自定义对象。如果在某些方面有某些问题,这可能是AHK本身的问题,而不是类的问题。
- 您不能从文本开始,您不能有一个段落或键。我无法想象这是一个大问题。
“=”在键名中不支持。
关于ini数据的几条注释:
- 没有值的键可以使用
- 尽管不推荐使用您的其他应用程序来访问相同的ini,但是“]”在段名称中是支持的。
- EasyIni在一个自定义对象中存储ini数据。这一定制对象的许多功劳都是Rbrtryn和Lexikos的工作,有关更多信息,请参见OrderedArray(日后会在网站分享)。由于有了OrderedArray的前期工作,我顺利完成了这个对象,使我能够维护ini文件的格式。如果在您的文件中删除了任何注释或新行,或者由于使用class_easyini而在您的文件中重新排序了任何部分或键,那么这是一个错误,请联系我!
这个库的重写也提高了整体的速度。实际上,Save()函数现在比旧的EasyIni类快了3629%!!
示例:
下面是一个测试,我将所有可能的字符值(从chr())中返回给一个ini。
写入内存的时间为1秒。
写入文件需要花费17秒(比旧类快3629%)。我测试没有那么快,应该是我的电脑性能的问题!
iAhkPID := DllCall("GetCurrentProcessId") Process, Priority, iAhkPID, H vIni := class_EasyIni("test.ini") ; Create Loop 65533 ; This many number of characters can be returned from chr() { if (!vIni.AddSection(chr(A_Index), A_Index, A_Index, sError)) sErrors .= sError "`n" } ; Takes ~2sec Msgbox Errors:`n%sErrors% vIni.Save() ; 17sec -- 3629% increase from old EasyIni!! return
这个测试显示了class_easyini的哪些字符是可读的。正如我之前提到的,某些奇怪的字符被组合到相同的部分中。如果您想了解更多,请先运行前面的示例,然后运行这个示例。
iAhkPID := DllCall("GetCurrentProcessId") Process, Priority, iAhkPID, H vIni := class_EasyIni("test.ini") ; Loaded in ~1.5Sec vIniCopy := new EasyIni() vIniCopy := vIniCopy.Copy(vIni, "test - copy.ini") ; Yes, this syntax is pretty odd/bad, but it is the only way I could get the copy function to work properly vIniCopy.Save() ; took ~8sec Msgbox saved! return }
添加1500个段,键和值将会花费小于1秒的时间来写入内存和一个ini。这个例子展示了区段和键是如何区分大小写的。它会给section a-z生成错误,因为a-z已经存在于ini中。
; Whole process takes ~1sec iAhkPID := DllCall("GetCurrentProcessId") Process, Priority, iAhkPID, H vIni := class_EasyIni("test1500.ini") ; Create Loop 1500 { if (!vIni.AddSection(chr(A_Index), A_Index, A_Index, sError)) sErrors .= sError "`n" } ; Takes < 1sec vIni.Save() return
创建一个ini,添加和修改段、键和值,并保存。
vIni := class_EasyIni("MyIni.ini") if (!vIni.AddSection("Section", "Key", "Val")) { Msgbox An unexpected error occurred. ; No errors expected for adding to a nearly blank ini. I just included this kind of handling in case there are any bugs. return } ; To modify areas later... if (!vIni.RenameSection("Section", "NewSection") || !vIni.RenameKey("NewSection", "Key", "NewKey")) { Msgbox An unexpected error occurred. return } ; if Newsection or Newkey are variables names, then NewKey := "NewKey" vIni[NewSection][NewKey] := "NewVal" ; or, in cases where you know the section name vIni.NewSection["NewKey"] := "NewVal" ; or, in cases where you know the section name and the key name vIni.NewSection.NewKey := "NewVal" vIni.Save() ; Write to ini return
从字符串中加载一个ini,并在一个文件中维护所有格式(包括注释和换行)
sIni:=" (LTrim ; One comment here... ; A comment here... [x] b=b a=a ; a comment there ; A second comment in [a] x=1 y=2 [[[a]]] a=a b=b ; A comment in this section ; A second comment in this section c=c ; A third comment in this section d=d [Section] ; and a comment here )" vIni := class_EasyIni("test.ini", sIni) for sSec, a in vIni for k, v in a Msgbox %sSec%`n%k%=%v% vIni.Save() return
IniWrite vs EasyIni:
iAhkPID := DllCall("GetCurrentProcessId") Process, Priority, iAhkPID, H vIni := class_EasyIni("test.ini") ; Create Loop 50000 { if (!vIni.AddSection(A_Index, A_Index, A_Index, sError)) sErrors .= sError "`n" } ; Takes ~1sec vIni.Save() ; 20sec Loop 50000 ; This many number of characters can be returned from chr() IniWrite, %A_Index%, IniWrite.ini, %A_Index%, %A_Index% ; Takes ~4min 4secs. 1162% return
?
使用了一下EASYini , 发现一个奇怪的现象: 比如,在银子输入法中,你配DATA目录下的配置文件yzime.ini删除,然后重新启动程序,这个时候照理说配置文件YZIME.INI应该已经创建了呀,然后查看目录发现没有文件创建创建.查看easyini,应该是在class_EasyIni()使用的时候就要创建吧?
可是没有,然后发现你如果把影子输入法的选项打开,这个时候配置文件就自动创建成功了
我无法理解,求何许人答疑解惑
使用这个类的save方法
ahk自带的ini有的时候竟然会造成卡顿…初始化也略微不方便…
支持?
感谢大佬
感谢大佬