# -*- coding: utf-8 -*-# # ------------------------------------------------------------------------------- # Name: Tools # Description: # Author: zhangchunhui # Date: 2019/1/27 # ------------------------------------------------------------------------------- import collections import os import sys import xml.etree.ElementTree as ET from pip._vendor import chardet ConfigPath = "./Config/Server" class DataParser: def __init__(self, fullFileName, fileName): """ 读取文件内容 :param fullFileName: :param fileName: """ # print(fullFileName) print(fileName) # f = open(fullFileName, "rb") # data = f.read() # print(chardet.detect(data)) # f.close() self.fileName = fileName.split('.')[0] file = open(fullFileName, 'r', encoding='GB18030') self.strCounts = file.read() self.list = self.strCounts.split('\n') file.close() def dealTitel(self): """ 处理标题 :return: """ self.titleDic = collections.OrderedDict() self.effectrow = [] if (len(self.list) > 4): titleList = self.list[0].split('\t') titleTypeList = self.list[1].split('\t') if titleList.__len__() != titleTypeList.__len__(): print("标题有问题 请检查:" + self.fileName) return for i in range(0, len(titleList)): titleStrName = titleList[i].strip() titleStrType = titleTypeList[i].strip() if (len(titleStrName) > 0 and len(titleStrType) > 0): self.titleDic[titleStrName] = titleStrType self.effectrow.append(i) else: print("配置文件出问题 请检查%s", self.fileName) def printTest(self): """ 输出查看 :return: """ for i in range(0, len(self.list)): str1 = self.list[i] print(str1) def writeProto3(self): """ 写出protoBuff3文件 :return: """ dom = ET.parse('ProtoTemplate.xml') importListStr = dom.getiterator("import") cousntStr = importListStr[0].text self.protoFileName = self.fileName + ".proto"; cousntStr += "message " + self.fileName cousntStr += "\n{\n" i = 1 for titleStr1 in self.titleDic.keys(): cousntStr += " " + getProtoType(self.titleDic[titleStr1]) + " " + titleStr1 + " = " + str(i) + ";\n" i += 1 cousntStr += "}\n" cousntStr += "message " + self.fileName + "_ARRAY\n" cousntStr += "{\n repeated " + self.fileName + " items = 1;"; cousntStr += "\n}\n" file = open("./protofile/" + self.protoFileName, 'w+', encoding='utf-8') file.write(cousntStr) file.close() def writeUTF8File(self): """ 写入文件信息 :return: """ file = open("./Out/" + self.fileName + ".txt", 'w+', encoding='utf-8') file.write(self.strCounts) file.close() def WritePythonCode(self): """ 生成proto文件 :return: """ command = "protoc --python_out=./ " + "./protofile/" + self.protoFileName os.system(command) def DealDataByte(self): data = "" try: self._module_name = self.fileName + "_pb2" sys.path.append(os.getcwd() + "./protofile") exec('from ' + self._module_name + ' import *') self._module = sys.modules[self._module_name] except Exception as e: print("Load error" + e + self.fileName) return item_array = getattr(self._module, self.fileName + '_ARRAY')() for i in range(3, len(self.list)): # print(self.list[i]) # 如果 id 是 空 直接跳过改行 str1 = self.list[i].strip() if (len(str1) > 0): str1List = str1.split('\t') if (len(str1List) > 0 and len(str1List[0]) > 0 and str1List[0].find("#") < 0): item = item_array.items.add() self._ParseLine(item, str1List) data = item_array.SerializeToString() self.writeDataByte(data) def _ParseLine(self, item, lineList): """ 初始化一行数据 :param item: :return: """ i = 0 for key in self.titleDic.keys(): # 如果 id 是 空 直接跳过改行 fild_value = getProtoValue(getProtoType(self.titleDic[key]), lineList[self.effectrow[i]]) item.__setattr__(key, fild_value) i += 1 def writeDataByte(self, data): """ 生成byte文件 :param data: :return: """ file_name = self.fileName + ".bin" # self._proto_name.lower() + ".bin" file = open("./bytedata/" + file_name, 'wb+') file.write(data) file.close() ProtoTypeDic = {"int": "int32", "string": "string", "float": "float"} def getProtoType(typeStr): """ 获取类型转换 :param typeStr: :return: """ typeStr = typeStr.lower() return ProtoTypeDic.get(typeStr, "nothing") def getProtoValue(typeStr, valueStr): """ 获取值信息 :param typeStr: :param valueStr: :return: """ try: if typeStr == "int32" or typeStr == "int64" \ or typeStr == "uint32" or typeStr == "uint64" \ or typeStr == "sint32" or typeStr == "sint64" \ or typeStr == "fixed32" or typeStr == "fixed64" \ or typeStr == "sfixed32" or typeStr == "sfixed64": if len(str(typeStr).strip()) <= 0: return 0 else: return int(valueStr) elif typeStr == "double" or typeStr == "float": if len(str(typeStr).strip()) <= 0: return float(0) else: return float(valueStr) elif typeStr == "string": return valueStr elif typeStr == "bytes": valueStr = valueStr.encode('utf-8') return valueStr else: return None except BaseException as e: print("parse cell(%u, %u) error, please check it, maybe type is wrong." % (typeStr, valueStr)) raise def gci(filepath): """ 读取所有的txt 文件 :param filepath: :return: """ files = os.listdir(filepath) for fi in files: fi_d = os.path.join(filepath, fi) if os.path.isdir(fi_d): gci(fi_d) else: txtInfo = DataParser(fi_d, fi) # txtInfo.writeUTF8File() # txtInfo.printTest() txtInfo.dealTitel() txtInfo.writeProto3() txtInfo.WritePythonCode() txtInfo.DealDataByte() if __name__ == '__main__': gci(ConfigPath)
Python通过protbuf 处理txt配置。序列化和反序列化
最新推荐文章于 2025-02-11 17:15:09 发布