/* ;~ 函数用于保存读写 任意维度 键值对类型 的 对象数据 (字典 / 数组 , 不包括 复杂类和对象) file_write_dict(dict, file, writeStartPos := 6) ;~ 参1 dict : 对象字典 ;~ 参2 file : 要保存字典 的 文件路径 ;~ 参3 writeStartPos : 写入文件起始位置, 在win7系统中似乎写入字节有bom存在, 故建议在起始6字节后写入字节 file_read_dict(file, readStartPos := 6) ;~ 参1 file : 读取字典 的 文件路径 ;~ 参2 readStartPos : 原理同上函数参3 */ ;~ 示例1, 保存简单字典 dict1 := {"abc": "" , "bbb": 555 , "ccc": "岁月如梭啊"} ;~ 写入字典 file_write_dict(dict1, A_ScriptDir "\dict1.dict") ;~ 读出字典 obj := file_read_dict(A_ScriptDir "\dict1.dict") a := "" for key, var in obj a .= key "=" var "`n" MsgBox, % a ;~ 示例2, 保存多维字典 dict2 := {"abc": [123, 661] , "bbb": ["bbbb1346sdfhzdf", "abcd`n可以嘛"] , "ccc": ["0x123", 0x6498]} ;~ 写入字典 file_write_dict(dict2, A_ScriptDir "\dict2.dict") ;~ 读出字典 obj := file_read_dict(A_ScriptDir "\dict2.dict") a := "" for key, var in obj a .= key "=" var[1] "-" var[2] "`n" MsgBox, % a return ;------------------------------------------ ;~ 读取文件字典 file_read_dict(file, readStartPos := 6) { static dataMinLen := 128 * 1024 local obj, dataLen, dictLen, keylen, key, pos, buff ret := {} VarSetCapacity(buff, dataMinLen, 0) ;~ 打开文件, 取数据总长 obj := FileOpen(file, "r") ;~ 读取尺寸信息 obj.RawRead(buff, readStartPos + 8) ;~ 数据总长 dataLen := NumGet(buff, readStartPos , "UInt") ;~ 字典总长 dictLen := NumGet(buff, readStartPos + 4 , "UInt") ;~ 具体数据起始端 pos := readStartPos + 8 ;~ 若空间不足, 则拓宽 if (dataLen > dataMinLen) VarSetCapacity(buff, dataLen, 0) ;~ 读取所有数据 后 关闭文件 obj.pos := 0 obj.RawRead(buff, datalen) obj.close() obj := "" ;~ 读取键值 loop %dictLen% { ;~ 取键名 keylen := NumGet(buff, pos, "UInt") pos += 4 key := StrGet(&buff + pos, keylen) pos += keylen ;~ 取值 ret[key] := file_read_dict_sub(buff, pos) } ;~ 释放内存 VarSetCapacity(buff, 0, 0) buff := "" return ret } ;~ file_read_dict() 函数尾 ;~ 读取文件字典 子函数, 递归函数 file_read_dict_sub(byref buff, byref pos) { static TYPE_STRING := 0 static TYPE_DICT := 1 varType := NumGet(buff, pos, "UChar") pos += 1 ;~ 为字符串时 if (varType = TYPE_STRING) { ret := "" ;~ len 此处为字符串数据长度 len := NumGet(buff, pos, "UInt") pos += 4 ret := (len = 0) ? "" : StrGet(&buff + pos, len) pos += len ;~ 为字典时 } else if (varType = TYPE_DICT) { ret := {} ;~ len 此处为 字典键值对数量 len := NumGet(buff, pos, "UInt") pos += 4 Loop %len% { ;~ len 此处为键长 len := NumGet(buff, pos, "UInt") pos += 4 key := StrGet(&buff + pos, keylen) pos += len ret[key] := file_read_dict_sub(buff, pos) } } return ret } ;~ file_read_dict_sub() 函数尾 ;------------------------------------------ ;~ 写入字典到文件 file_write_dict(dict, file, writeStartPos := 6) { static dataMinLen := 128 * 1024 local buff, buffLen, key, var, pos, obj ;~ 若传入首位参数非字典, 直接返回0 if not IsObject(dict) return 0 buffLen := dataMinLen VarSetCapacity(buff, buffLen, 0) ;~ 预留 4 byte 放置数据总长 pos := writeStartPos + 4 ;~ 前两个数据为 整体数据长度, 键值对 数量, 无符号整形 numput(dict.count(), buff, pos, "UInt") pos += 4 for key, var in dict { ;~ 1. 写入键: ;~ 1.1 键长 UInt 4Byte ;~ 1.2 键内容 String ... file_write_dict_str(key, buff, buffLen, pos) ;~ 2. 写入值: ;~ 2.1 值类型 UChar 1Byte 0>字符串 1>对象 ;~ 2.2 写入长度 UInt 4Byte ;~ 2.2.1. 为 字符串 时, 写入 值长度 ;~ 2.2.2. 为 字典 时, 写入 键值对数量 ;~ 2.3 写入内容 ... file_write_dict_obj(var, buff, buffLen, pos) } ;~ 将数据 总长 写入起始位置 writeStartPos NumPut(pos, buff, writeStartPos, "UInt") ;~ 将 缓存变量写入文件 obj := FileOpen(file, "w") obj.RawWrite(buff, pos) obj.close() obj := "" ;~ 释放内存 VarSetCapacity(buff, 0, 0) buff := "" ;~ 返回写入总长 return pos } ;~ file_write_dict() 函数尾 ;~ 写入字典到文件 子函数, 写入字符串 file_write_dict_str(str, byref buff, byref buffLen, byref pos) { static dataMinLen := 128 * 1024 local len, finalLen, ls, i, v ;~ 求所需字符串长度 len := (str = "") ? 0 : StrPut(str) * 2 ;~ 剩余总长: 起始点 + 长度量整形 + 数据总长 finalLen := pos + 4 + len ;~ 最终长度若不足, 则增加长度 if (finalLen > buffLen) { ;~ 读出所有字节 ls := [] Loop, % buffLen ls.push(NumGet(buff, A_Index - 1, "UChar")) ;~ 最终尺寸 + 1024 * 128 buffLen := finalLen + dataMinLen ;~ 重置缓存区尺寸 VarSetCapacity(buff, buffLen, 0) ;~ 重新写入数据 for i, v in ls NumPut(v, buff, i - 1, "UChar") ls := "" } ;~ 写入字符串长度 NumPut(len, buff, pos, "Uint") pos += 4 ;~ 若字符串不为空, 写入字符串 if (str <> "") { StrPut(str, &buff + pos, len) pos += len } } ;~ file_write_dict_str() 函数尾 ;~ 写入字典到文件 子函数, 写入字符串 或 字典 file_write_dict_obj(obj, byref buff, byref buffLen, byref pos) { static dataMinLen := 128 * 1024 static TYPE_STRING := 0 static TYPE_DICT := 1 ;~ 若剩余尺寸不足5位(不足存放类型和长度), 拓宽 缓存变量 if (buffLen - pos <= 5) { ;~ 读出所有字节 ls := [] Loop, % buffLen ls.push(NumGet(buff, A_Index - 1, "UChar")) ;~ 最终尺寸 + 1024 * 128 buffLen += dataMinLen ;~ 重置缓存区尺寸 VarSetCapacity(buff, buffLen, 0) ;~ 重新写入数据 for key, var in ls NumPut(var, buff, i - 1, "UChar") ls := "" } if not IsObject(obj) { ;~ 写入 类型 NumPut(TYPE_STRING, buff, pos, "UChar") pos += 1 file_write_dict_str(obj, buff, buffLen, pos) } else { ;~ 写入 类型 NumPut(TYPE_DICT, buff, pos, "UChar") pos += 1 ;~ 字典 长度 NumPut(obj.count(), buff, pos, "UInt") pos += 4 for key, var in obj { ;~ 写入键 file_write_dict_str(key, buff, buffLen, pos) ;~ 写入值 file_write_dict_obj(var, buff, buffLen, pos) } } } ;~ file_write_dict_obj() 函数尾
声明:站内资源为整理优化好的代码上传分享与学习研究,如果是开源代码基本都会标明出处,方便大家扩展学习路径。请不要恶意搬运,破坏站长辛苦整理维护的劳动成果。本站为爱好者分享站点,所有内容不作为商业行为。如若本站上传内容侵犯了原著者的合法权益,请联系我们进行删除下架。
评论(0)