由于平时工作需要,经常要把csv文件修改成utf-8的编码,但是这个操作异常繁琐,excel和wps无法直接把保存,必须右键记事本另存为utf-8。于是乎我就在想我是不是可以用我这只会基本语法的脑子写一个一键改编码的脚本呢
因为csv文件都在一个文件夹下并且没有其他文件所以思路很简单:遍历获取文件夹下所有csv文件名,把文件转成utf-8。 可是转成utf-8遇到了几个困难。查了资料了解了转码可以使用decode、encode来。
def handleEncoding(original_file,newfile): #自动给csv转utf-8 #newfile=original_file[0:original_file.rfind(.)]+'_copy.csv' f=open(original_file,'rb+') content=f.read()#读取文件内容 with open(newfile, 'wb') as f2: f2.write(content.decode('ANSI').encode('utf-8')) #把文件从ANSI转成我utf-8 f2.close()
可是这会出现一个问题就是,如果遍历到一个本身就是utf-8的就会报错。现在想想好像可以用try except尝试把utf-8再转一遍utf-8。不过我当时想的是我需要先判断文件的编码格式,于是乎又从网上找到了一个东西叫chardet,这个库可以用来检测文件的编码,原理是一行一行读内容,直到判断出结果就返回一个文件信息的数组,下面代码我直接抄的网上的,其实也不难理解,我只改了后面的返回类型
def get_encode_info(file): with open(file, 'rb') as f: detector = UniversalDetector() for line in f.readlines(): detector.feed(line) if detector.done: break detector.close() #这一步之后detector就已经有检测出的编码结果了 if detector.result['encoding'] == 'utf-8' : return False else: print(detector.result['encoding']) return True
把这两个函数组合一下再把文件名数组中的文件名一个一个传进去,脚本就ok了。但是实际体验其实不算太好,面对着上百个csv文件着实有点慢了点
于是我就想怎么才可以让这个东西跑的快一点呢?我重新看了下自己写的代码,发现是代码中遍历的地方太多了。 遍历文件名存入数组->遍历数组把文件名取出传入编码检测函数->编码检测函数遍历内容->给出判断执行编码转换。 3个地方遍历可想而知这速度有多慢。
后来我想到,其实在遍历文件名的时候就可以直接进行编码检测筛选一遍先,何必之后再从数组里遍历所有文件进行检测呢
if os.path.isfile(com_path) and get_encode_info(com_path): #if判断条件增加了编码检测 path_list.append(com_path)
试了一下感觉比之前快了,可是这个速度还是让我有点不耐烦。我想到把编码检测当作条件判断相当于是给所有文件做了一步检测,可能就是这个检测拖慢了速度,我能不能把缩小这个检测范围呢?
第二天上班时我想到我平时的使用场景是修改csv文件后立马用记事本另存为utf-8,那我可不可以只检测最近修改的文件从而达到缩小编码检测的范围。 有了想法后立马百度,了解了如何获取本地时间、文件修改时间以及时间戳的概念后,实现起来还是比较简单
def isYourEditFile(file): #获得文件当前时间和系统当前时间的时间戳,让两者相减,小于两小时的返回True.目的是为了进一步缩小需要进行编码检测的文件范围,提高转化速度 filetime =os.stat(file) #获取文件的系统信息,返回的是数组里面包括最近修改时间 gap = time.time() - filetime.st_mtime if gap <= 7200 : #7200秒内财修改的文件返回True return True else: return False
获取文件名数组变成了这样
if os.path.isfile(com_path) and isYourEditFile(com_path): if get_encode_info(com_path): path_list.append(com_path)
这样子就可以只检测2小时内修改的文件了,但是具体效果如何还没测试,得明早去公司尝试一下。
以前尝试看了很多种类的网课和书,但都半途而废一直停留在基础语法的层面上,这个脚本是我第一次用代码解决实际需求的尝试。虽然可能很简易,不过也让我意识到了实现还只是基本要求面向百度拼装拼装都可以跑起来。但如何更有效率的执行才是根本,而这可能就需要用到数据结构和算法的经验。
另一点是解决实际问题让我产生了一丝成就感,希望能再接再厉,下一步是学一门真正的底层语言和数据结构。希望以后能通过自学成为一名真正的程序员