//ini 配置文件 import fsys; namespace fsys; var getIniPath = function(path,utf16){ if(!path) error("请指定 INI 文件路径",3); var fullpath = ..io.exist(path); if( fullpath) return fullpath; var defult = ..string.load(path) if(#defult){ ..string.save(path ,defult) return ..io.exist(path); } ..string.save(path ,utf16?'\xFF\xFE':'') return path; } class ini{ ctor(path,utf16){ path = getIniPath(path,utf16); }; read = function(app,key ,default = ""){ var getlen=512; var len,val = GetPrivateProfileString(app,key,default,getlen*2,getlen,path); while(len >= getlen-2){ getlen+=512; len,val = GetPrivateProfileString(app,key,default,getlen*2,getlen,path) } if(!len) return; if(!key) { return ..string.split(..string.fromUtf16(val,,len-1),'\0'); } else { return ..string.fromUtf16(val,,len); } }; write = function(app,key,str){ WritePrivateProfileString(app,key,str?tostring(str):null,path); }; readSectionNames = function(){ return this.read(); } readKeys = function(app){ return this.read(app); } getSectionNames = function(){ var getlen=512 var len,val = GetPrivateProfileSectionNames( getlen*2,getlen,path); while(len >= getlen-2){ getlen+=512; len,val = GetPrivateProfileSectionNames( getlen*2,getlen,path); } if(!len) return null; val = ..string.fromUtf16( val,,(len-1) ); return ..string.split(val,'\0'); } getSection = function(app){ return app?section(path,app); } eachSection = function(p){ var secs = this.getSectionNames() : {}; var i = 0; return function(){ i++; if( p ){ while(secs[i] && !..string.find(secs[i],p) ){ i++; } } return secs[i]?section(path,secs[i]) ; } } } namespace ini{ GetPrivateProfileString = ::Kernel32.api("GetPrivateProfileStringW","int(ustring lpApplicationName,ustring lpKeyName,ustring lpDefault,string & lpReturnedstring,int nSize,ustring lpFileName)"); WritePrivateProfileString = Kernel32.api("WritePrivateProfileStringW","int(ustring lpAppName,ustring lpKeyName,usting lpString,ustring.lpFileName)"); GetPrivateProfileSectionNames = ::Kernel32.api("GetPrivateProfileSectionNamesW","int(string &buffer,int size,ustring file)"); } class ini.section{ ctor(path,app){ if(!app ) error("请指定 INI 文件[小节名字]",2) path = getIniPath(path); var getlen=512 var len,val = GetPrivateProfileSection(app, getlen*2,getlen,path) while(len >= getlen-2){ getlen+=512; len,val = GetPrivateProfileSection(app, getlen*2,getlen,path) } if(len){ val = ..string.fromUtf16( val,,(len-1)); var tlist = ..string.split(val,'\0'); var pos,k; for( i,v in tlist){ pos = ..string.find(v,"@="); if(pos){ k = ..string.trim(..string.left(v,pos-1)); this[k] = ..string.trim( ..string.slice(v,pos+1) ); } } } this@ = { save = function(){ var t = {} for(k,v in this){ if(type(v)!=type.function){ ..table.push(t,k); ..table.push(t,"="); ..table.push(t,v); ..table.push(t,'\0'); } } ..table.push(t,'\0'); ..table.push(t,'\0'); var v = ..string.join(t ); WritePrivateProfileSection( app,..string.toUtf16(v),path); } name = function(){ return app; } } //将save函数放在元表中,这样当使用for in遍历ini.section对象时,就看不到save函数 this@._get = this@ } } namespace ini.section{ GetPrivateProfileSection = ::Kernel32.api("GetPrivateProfileSectionW","int(ustring app,string &buffer,int size,ustring file)"); WritePrivateProfileSection = ::Kernel32.api("WritePrivateProfileSectionW","int(ustring app,string buffer,ustring file)"); } /**intellisense() fsys.ini = 用于 INI 文件读写\n\n如果文件已存在并使用 UTF-16 编码存储,则文件保持原编码。\n否则使用 ANSI 编码存储 INI 文件。\n在 aardio 中仍以 UTF-8 编码读写,读写时自动转换编码。\n改用 string.ini,JSON, fsys.config 则可始终使用 UTF-8 编码读写配置文件。 fsys.ini( = 打开 INI 文件对象。\n如果文件未存在并且存在同路径的资源文件,\n则先将资源文件保存到本地文件。 fsys.ini(.(path) = 打开 path 参数指定路径的INI 文件对象。\n如果文件已存在并使用 UTF-16 编码存储,则继续以此编码存储 INI 文件。\n否则使用 ANSI 编码存储 INI 文件。\n在 aardio 中仍以 UTF-8 编码读写,读写时自动转换编码。 fsys.ini(.(path,true) = = 打开 path 参数指定路径的 INI 文件对象。\n如果文件未存在则创建文件并添加 UTF-16 LE BOM 头,并继续以此编码存储 INI 文件。\n如果文件已存在并使用 UTF-16 编码存储,则继续以此编码存储 INI 文件。\n否则使用 ANSI 编码存储 INI 。\n在 aardio 中仍以 UTF-8 编码读写,读写时自动转换编码。 !fsysIniFile.read("小节名","键名")= 读取 INI 指字小节的指键键\n可选使用参数 @3 指定默认值\n成功返回读取的值,失败返回 null\n\n如果指定键名成功应返回字符串值\n不指定键名成功返回小节下所有键值组成的字符串数组\n返回字符串、数组、null 时都可以使用#操作符取长度,null 的长度为0,\nnull,0 转换为逻辑值都等价于 false !fsysIniFile.write("小节名","键名","新值") = 写 INI 文件\n健名为 null 删除指定的小节\n值为 null 删除指定的键名 !fsysIniFile.readSectionNames() = 返回小节名称组成的字符串数组 !fsysIniFile.readKeys("小节名") = 返回指定小节中所有键名组成的字符串数组 !fsysIniFile.getSectionNames() = 获取所有小节名字,返回字符串数组. !fsysIniFile.getSection("__/*小节名*/") = 读取或添加小节对象,可直接读写成员 !inisection.name() = 返回小节名称 !inisection.save() = 保存更改到 INI 文件 !inisection.? = 可输入任意属性名,读写小节属性。\n成功返回字符串值,失败返回 null 。 !fsysIniFile.getSection() = !inisection. !fsysIniFile.eachSection() = !inisection. !fsysIniFile.eachSection() = @for section in ??.eachSection(__/*可选用模式匹配搜索*/) { for(k,v in section){ /*k 为键,v 为值,section 为当前遍历到的小节*/ } } fsys.ini() = !fsysIniFile. end intellisense**/