大家好,我是讯享网,很高兴认识大家。
最近手机经常提示储藏室空不足,主要是微信和QQ群里收到的文件太多,平时不怎么整理。我把这些文件从手机里复制了出来,打算整理一下,把删除的文件全部删除,把要备份的文件分门别类存放在电脑或者网盘里。突然发现一个问题,就是手机里有很多重复的文件,文件名不同,内容却完全一样。这让我很头疼。手动一个个对比文件,然后删除重复的文件,会累死我的。
于是我有了一个想法,用Python写一个小工具,把所有重复的文件都给我列出来,我批量检查删除就行了。
这个小工具是用Python3.8.10和wxPython4.2.0开发的,主要通过解决这些问题来实现:
遍历指定文件夹中的所有文件生成所有文件的MD5哈希值并保存在字典里,字典的key是哈希值,value是一个列表,列表存放所有哈希值一样的文件路径。为了不让界面卡死,在文件处理过程中,需要使用单独的线程。设计GUI,这里我是纯手工写的GUI代码。wxPython官方的示例很齐全,很多控件示例拷过来改改就可以了。调用系统函数打开文件、打开文件所在位置、删除文件。
张贴以下关键代码:
遍历文件
#遍历文件并将所有文件的路径放在一个列表中。def disk _ walk(file path):path _ collection =[]for dirpath,dirnames,filename in OS . walk(file path):for file in Filenames:full path = OS . path . join(dirpath,file)path _ collection . append(full path)return path _ collection生成文件的MD5哈希值
#生成文件的md5值。通过比较文件的MD5值,可以判断两个文件是否一致def make _ hash(file _ path):try:MD5 = hashelib . MD5()#用open创建一个MD5算法对象(file _ path,& # 39;rb & # 39)作为f: #要打开一个文件,必须是& # 39;rb & # 39开启模式while 1: data = f.read(1024) #由于是文件,每次只读取固定字节if数据:# Update MD5。读取内容不是空时更新(数据)else停止更新break ret = md5.hex digest () #获取该文件除OSError以外的md5值:print(& # 39;权限被拒绝:% s & # 39% file _ path)return None ret文件大小打印格式
#文件大小打印格式def格式文件大小(size):对于x in[& # 39;B&第39名;, ‘KB & # 39, ‘MB & # 39, ‘GB & # 39, ‘TB & # 39, ‘PB & # 39]:如果大小& lt1024.0:return & # 34;% 3.2f % s & # 34% (size,x) size /= 1024.0一个单独的线程处理遍历文件和生成MD5哈希值的任务。
def PopulateList(self,path,info):self . info = info self . list . deleteallitems()self . record . clear()_ thread . start _ new _ thread(self。Run,(path,)def Run(self,filepath): # wx。BeginBusyCursor()files = disk _ walk(file path)count = len(files)self . gauge . set range(count)for idx,f in enumerate(files):hash_value = make _ hash(f)如果hash _ value为None:continue if hash _ value in self . record:df = self . record[hash _ value]df . append(f)else:df =[f]self . record[hash _ value]= dfwx . postevent(self . list,updateListEvent (file = f,total = count,index = idx
# open file def on openfile (self,event):index = self . list . get first selected()file path = self . get column text(index,3) os.startfile (filepath)打开文件的位置
#打开文件的位置是defonopenfilelocation (self,event):index = self . list . getfirstselected()file path = self . getcolumntext(index,3)OS . system(f & # 39;资源管理器/选择,{文件路径} & # 39;)删除勾选的文件。
#删除选中的文件def OnDeleteFile(self,event):item count = self . list . getitemcount()items checked =[I for I in range(item count)if self . list . isitemchecked(item = I)]if len(items checked)= = 0:wx。MessageBox(& # 39;请检查要删除的文件& # 39;, ‘消息& # 39;,wx。好| wx。ICON_INFORMATION) else: rs = wx。MessageBox(& # 39;您确定要删除所选文件吗?’, ‘确认& # 39;,wx.yes _ no | wx.icon _ warning)如果RS = = wx . yes:Itemschecked . reverse()#列表是反向的,从后向前删除,避免由于ListCtrl的项索引变化而导致删除失败对于items checked中的索引:try:file _ path = self . getcolumntext(index,3)OS . remove(file _ path)self . list . delete Item(index)except OS错误:print(& # 39;权限被拒绝:% s & # 39% file_path)wxPython具有自定义的事件处理机制。
首先定义事件。
# this创建一个新的事件类和一个evt绑定函数(updateListEvent,evt _ update _ bar graph)= wx . lib . new event . new event()将事件绑定到UI控件。
自我。list.bind (evt _ update _ bargraph,self。更新时)事件处理方法
def OnUpdate(self,event):self . info . set label(event . file)self . gauge . setvalue(event . index)if event . index = = event . total:self . info . set label(& # 39;已完成扫描& # 39;)……每次在独立线程中处理文件时,都会触发一个事件来通知UI控件更新。
wx.PostEvent(self.list, UpdateListEvent(file=f, total=count, index=idx + 1))
本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://51itzy.com/12864.html