python学习笔记~INI、REG文件读取函数(自动修复)

引入configparser,直接read整个INI文件,再调用get即可。但需要注意的是,如果INI文件本身不太规范,就会报各种错,而这又常常不可避免的。本文自定义函数通过try...except..来自动纠正再重读。

此外,注册表导出文件大概齐就是INI文件格式,但取初一行的声明也会被认定为没有SECTION头而报错。本文也进行了自动纠正。

极大概率是早有人造过更好的轮子,我写在这里权当作自己学习Python的笔记。功能、特色如下:

  1. getINIValue函数三个参数,iniFile, section, option应该不用特别说明;
  2.  若iniFile本身不存在或未知异常,返回None,同时输出报错信息;
  3.  INI文件编码自动尝试,目前顺序为gb2312 utf-8 utf-16 gbk gb18030;
  4. INI文件内容不规范(section或option重复异常即configparser.DuplicateSectionError, configparser.DuplicateOptionError)自动纠正(注释后面的,以前面的为准);
  5. 注册表导出Reg文件不符合INI规范(缺少SECTION头异常即configparser.MissingSectionHeaderError)自动纠正(注释最初行);
  6. 找不到Option(考虑到一种情况:上位指定.reg的Option时没加",自动追加);
  7. 自动纠正INI文件时产生的备份文件自动删除。

Python源码如下,欢迎讨论指正....

  1 import configparser
  2 import os
  3 
  4 bakpostfix = '.ibk'
  5 
  6 ## [修正不规则INI文件]
  7 def __iniFileFix(errorline, iniFile, encoding):
  8     # 备份INI文件名
  9     newIniFile = iniFile + bakpostfix
 10 
 11     try:
 12         fr = open(iniFile, 'r', encoding=encoding)
 13         fw = open(newIniFile, 'w', encoding=encoding)
 14         # 逐行读取
 15         line = fr.readline()
 16         lineno = 1
 17         while line != '':
 18             # 若到了问题行,则注释它
 19             if lineno == int(errorline):
 20                 line = '; ' + line
 21             # 逐行写入(修正后)
 22             fw.writelines(line)
 23             line = fr.readline()
 24             lineno += 1
 25         fr.close()
 26         fw.close()
 27     except Exception as e:
 28         # 异常时返回报错信息
 29         error = 'Error:[{0}]'.format(e)
 30         print(error)
 31         return error
 32     # 正常时返回新文件名
 33     return newIniFile
 34 
 35 ## [读取INI文件]
 36 def getINIValue(iniFile, section, option):
 37     config = configparser.ConfigParser()
 38     value = ''
 39 
 40     # 备份文件
 41     bBakFile = False
 42 
 43     # 异常:文件不存在
 44     if (os.path.isfile(iniFile) == False):
 45         print('Error: file "{0}" not exists...'.format(iniFile))
 46         return None
 47 
 48     bException = True
 49     # 尝试编码的次数
 50     counter = 1
 51     # 多次循环尝试修正INI为正确的格式,直到正常或遇到无法处理的异常
 52     while bException:
 53         try:
 54             encoding = ''
 55             # 依次进行如下编码打开尝试(后续根据需要添加)
 56             if counter == 1: encoding = 'gb2312'
 57             if counter == 2: encoding = 'utf-8'
 58             if counter == 3: encoding = 'utf-16'
 59             if counter == 4: encoding = 'gbk'
 60             if counter == 5: encoding = 'gb18030'
 61             if counter == 6:
 62                 # 暂无法处理的编码
 63                 print('Error: encoding unknown...')
 64                 return None
 65             config.read(iniFile, encoding=encoding)
 66             bException = False
 67         except UnicodeDecodeError as e:
 68             # 编码异常
 69             print('Error:[{0}]'.format(e))
 70             counter += 1
 71         except (configparser.DuplicateSectionError, configparser.DuplicateOptionError) as e:
 72             # SECTION重复异常
 73             # Option重复异常
 74             print('Error:[{0}]'.format(e))
 75             excep = '{0}'.format(e)
 76             errorline = excep[excep.find(' [line ') + len(' [line '):excep.find(']', excep.find(' [line '))]
 77             iniFile = __iniFileFix(errorline, iniFile, encoding)
 78             if iniFile.find('Error:[') == 0:
 79                 return None
 80             bBakFile = True
 81         except configparser.MissingSectionHeaderError as e:
 82             # 缺少SECTION头异常
 83             print('Error:[{0}]'.format(e))
 84             excep = '{0}'.format(e)
 85             errorline = excep[excep.find(', line: ') + len(', line: '):excep.find('\n', excep.find(', line: '))]
 86             iniFile = __iniFileFix(errorline, iniFile, encoding)
 87             if iniFile.find('Error:[') == 0:
 88                 return None
 89             bBakFile = True
 90         except Exception as e:
 91             # 未知新异常(后续根据需要追加)
 92             print('Error:[{0}]'.format(e))
 93             return None
 94 
 95     # 删除INI备份文件
 96     if bBakFile == True:
 97         # 可能存在多个INI备份,循环删除
 98         bMoreBakFile = True
 99         while (bMoreBakFile):
100             os.remove(iniFile)
101             iniFile = iniFile[0:iniFile.rfind(bakpostfix)]
102             if iniFile.rfind(bakpostfix) == -1 :
103                 bMoreBakFile = False
104 
105     # 多次循环尝试修正INI为正确的格式,直到正常或遇到无法处理的异常
106     bException = True
107     while bException:
108         try:
109             value = config.get(section, option)
110             bException = False
111         except configparser.NoSectionError as e:
112             # 找不到SECTION
113             print('Error:[{0}]'.format(e))
114             return None
115         except configparser.NoOptionError as e:
116             # 找不到Option(考虑到一种情况:上位指定.reg的Option时没加",自动追加)
117             print('Error:[{0}]'.format(e))
118             if option[0] != '"' and option[len(option)-1] != '"':
119                 option = '"' + option + '"'
120             else :
121                 return None
122         except Exception as e:
123             # 未知新异常(后续根据需要追加)
124             print('Error:[{0}]'.format(e))
125             return None
126 
127     return value

猜你喜欢

转载自www.cnblogs.com/mxcher/p/9571938.html