【Python】文件批量对比

【Python】文件批量对比

应用场景

写这个的原因是因为公司有个对外的项目需要发包给其他人,但是包很大有几十个G,每次版本迭代都要重新发包的话就很麻烦,所以写了这个,目的就是能减小发送包的大小,这样就能让那边的人在原来的包上做修改(其实也没啥要改的,我都改弄完了到时候发过去直接循行个.exe就完事了,这要是都不会我真的就要骂人了!!!😕)

代码分析

注意嗷,这里给的代码只是部分代码,并且为了方便分析,代码顺序有一丢丢不同, 完整代码请下拉到源码下载!

import os
import shutil
from filecmp import dircmp

这里用到的三个库os, shutil, dircmp都是Python的标准库,不需要另外下载,其中os和shutil用来处理创建、删除、拷贝文件,dircmp用来对比文件信息

if __name__ == '__main__':
    old = 'old'
    cur = 'cur'
    new = 'new'
    
    copydir = os.path.realpath(os.curdir) + '\\' + new
    shutil.rmtree(copydir, ignore_errors=True)
    os.mkdir(copydir)

    #打开文件
    myadd = open('Add.txt', 'w+', encoding='utf-8')
    mydiff = open('Diff.txt', 'w+', encoding='utf-8')
    myremove = open('Remove.txt', 'w+', encoding='utf-8')

    CheckDiff(dircmp(old, cur, ['*.o', '*.lo', '*.la', '*.al', '.libs', '*.so', '*.so.[0-9]*', 
    '*.a', '*.pyc', '*.pyo __pycache__', '*.rej', '*~', '#*#', '.#*', '.*.swp', '.DS_Store', '[Tt]humbs.db']), '\\')

    #关闭文件
    myadd.close()
    mydiff.close()
    myremove.close()

    #拷贝删除程序和删除文件到项目中
    shutil.copy2('./Remove.txt', copydir + '\\Remove.txt')
    shutil.copy2('./AutoRemove.exe', copydir + '\\AutoRemove.exe')

这个就是主函数啦,很简单吧,解释一下变量的意思,old就是旧版本文件夹,cur是当前版本文件夹,new是需要发送给他们的新建文件夹,然后myadd,mydiff,myremove就是字面意思(没错,我就是起名废柴😀),分别代表用来记录添加、修改、删除的文件夹及文件名

这个程序会将添加、修改的文件和需要删除的记录文件以及自动删除程序拷贝放到新建文件夹中,然后只需要把新建文件夹发给对方,让对方运行其中的自动删除程序就OK了

def CheckDiff(mydcmp, dir):
    for name in mydcmp.right_only:
        str = os.path.realpath(os.curdir) + '\\' +cur + dir + name
        if(os.path.isfile(str)):
            myadd.write(dir + name + '\n')
            os.makedirs(copydir + dir, exist_ok=True)
            shutil.copy2(str, copydir + dir + name)
        else:
            str1 = os.path.realpath(os.curdir) + '\\' + old + dir + name
            if not os.path.exists(str1):
                myadd.write(dir + name + '\\' + '\n')
                os.makedirs(copydir + dir + name, exist_ok=True)
                shutil.copytree(str, copydir + dir + name, dirs_exist_ok=True)
    for name in mydcmp.diff_files:
        str = os.path.realpath(os.curdir) + '\\' +cur + dir + name
        if os.path.isfile(str):
            mydiff.write(dir + name + '\n')
            os.makedirs(copydir + dir, exist_ok=True)
            shutil.copy2(str, copydir + dir + name)
    for name in mydcmp.left_only:
        str = os.path.realpath(os.curdir) + '\\' + old + dir + name
        if os.path.isfile(str):
            myremove.write(dir + name + '\n')
        else:
            str1 = os.path.realpath(os.curdir) + '\\' +cur + dir + name
            if not os.path.exists(str1):
                myremove.write(dir + name + '\\' + '\n')
    for subdir in mydcmp.subdirs.keys():
         CheckDiff(mydcmp.subdirs[subdir], dir + subdir + '\\')

该程序的核心功能都在这里了,这里的right_only是仅存在于新版本中的路径,即新增的文件,left_only是仅存在与旧版本中的路径,即需要删除的文件,diff_files是新旧版本不同的文件,即需要修改的文件

最后递归执行该函数指导所有文件夹都比对完成

源码下载

源码下载
核心代码都在上面,不想下载源码的话自己拷贝一下改一改也能用

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
# -*- coding: utf-8 -*- ''' 事件传播有两种类型事件:基本事件和命令事件。它们不同于传播方式。事件传播是指事件从子部件 传到父部件和父窗口的父窗口等。基本事件不传播,命令事件传播。比如wx.CloseEvent是一个基本事件。 它没有传到父窗口的一样。默认情况下, 这种事件在一个事件处理器里就停止传播。如果想继续传播, 我们必须调用Skip()方法。 用event.Skip()方法调用事件默认处理程序 ''' import wx import threading from os.path import getsize def CompFile(win,file1,file2): try: if getsize(file1) != getsize(file2): win.m_staticText4.SetFont(win.font) win.m_staticText4.SetForegroundColour(wx.Colour(255,0,0)) win.m_staticText4.SetLabelText('文件比较结果:两个文件比较结果不一样') win.m_button4.SetFocus() win.m_button4.SetDefault() return f1=open(file1,'rb') f2=open(file2,'rb') except Exception as e: win.m_staticText4.SetFont(win.font) win.m_staticText4.SetForegroundColour(wx.Colour(255,0,255)) win.m_staticText4.SetLabelText('打开文件错误:'+e.strerror) win.m_button4.SetFocus() win.m_button4.SetDefault() else: for f11,f22 in zip(f1.read(),f2.read()): if f11 != f22: win.m_staticText4.SetFont(win.font) win.m_staticText4.SetForegroundColour(wx.Colour(255,0,0)) win.m_staticText4.SetLabelText('文件比较结果:两个文件比较结果不一样') win.m_button4.SetFocus() win.m_button4.SetDefault() return else: win.m_staticText4.SetFont(win.font) win.m_staticText4.SetForegroundColour(wx.Colour(0,155,0)) win.m_staticText4.SetLabelText('文件比较结果:两个文件比较结果一模一样') win.m_button4.SetFocus() win.m_button4.SetDefault() finally: try: f1.close() f1.close() except: pass class FileDrop(wx.FileDropTarget): def __init__(self, textctrl): wx.FileDropTarget.__init__(self) self.textctrl = textctrl def OnDropFiles(self, x, y, filePath): # 当文件被拖入grid后,会调用此方法 self.textctrl.SetValue(''.join(filePath)) return 1 class Mywin(wx.Dialog): def __init__(self,parent,title): super().__init__(parent,title=title,size=(500,200),style=wx.DEFAULT_FRAME_STYLE|wx.STAY_ON_TOP) self.InitUI() def InitUI(self): icon = wx.Icon('33.ico', wx.BITMAP_TYPE_ICO) self.SetIcon(icon) self.SetSizeHints( wx.DefaultSize, wx.DefaultSize ) bSizer7 = wx.BoxSizer( wx.VERTICAL ) bSizer8 = wx.BoxSizer( wx.HORIZONTAL ) self.m_staticText2 = wx.StaticText( self, wx.ID_ANY, u"第一个文件", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_staticText2.Wrap( -1 ) bSizer8.Add( self.m_staticText2, 0, wx.ALL, 10 ) self.m_textCtrl3 = wx.TextCtrl( self, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_textCtrl3.Bind(wx.EVT_TEXT_ENTER,self.onTextChange) self.fileDrop = FileDrop(self.m_textCtrl3) self.m_textCtrl3.SetDropTarget(self.fileDrop) bSizer8.Add( self.m_textCtrl3, 1, wx.ALL, 5 ) bSizer7.Add( bSizer8, 0, wx.EXPAND, 5 ) bSizer9 = wx.BoxSizer( wx.HORIZONTAL ) self.m_staticText3 = wx.StaticText( self, wx.ID_ANY, u"第二个文件", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_staticText3.Wrap( -1 ) bSizer9.Add( self.m_staticText3, 0, wx.ALL, 10 ) self.m_textCtrl4 = wx.TextCtrl( self, 5001, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 ) self.fileDrop1 = FileDrop(self.m_textCtrl4) self.m_textCtrl4.SetDropTarget(self.fileDrop1) bSizer9.Add( self.m_textCtrl4, 1, wx.ALL, 5 ) bSizer7.Add( bSizer9, 0, wx.EXPAND, 5 ) bSizer11 = wx.BoxSizer( wx.HORIZONTAL ) self.m_button4 = wx.Button( self, wx.ID_ANY, u"文件比较", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_button4.Bind(wx.EVT_BUTTON,self.OnButton) self.m_button4.SetFocus() self.m_button4.SetDefault() bSizer11.Add( self.m_button4, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 ) self.m_button5 = wx.Button( self, wx.ID_ANY, u"清空文本", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_button5.Bind(wx.EVT_BUTTON,self.OnClear) bSizer11.Add( self.m_button5, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 ) bSizer7.Add( bSizer11, 0, wx.ALIGN_CENTER|wx.ALIGN_LEFT, 5 ) bSizer12 = wx.BoxSizer( wx.VERTICAL ) self.font=wx.Font(16,wx.ROMAN,wx.NORMAL,wx.NORMAL) self.font.FaceName="微软雅黑" self.m_staticText4 = wx.StaticText( self, wx.ID_ANY, u"文件比较结果:", wx.DefaultPosition, wx.DefaultSize, 0 ) self.m_staticText4.SetFont(self.font) self.m_staticText4.Wrap( -1 ) bSizer12.Add( self.m_staticText4, 0, wx.ALL, 5 ) bSizer7.Add( bSizer12, 1, wx.EXPAND, 5 ) self.SetSizer( bSizer7 ) self.Layout() self.Bind(wx.EVT_CLOSE,self.onClose) self.Centre( wx.BOTH ) self.Show() def onTextChange(self,evt): self.m_button4.SetFocus() self.m_button4.SetDefault() def OnButton(self,event): file1=self.m_textCtrl3.GetValue() file2=self.m_textCtrl4.GetValue() t1=threading.Thread(target=CompFile,args=(self,file1,file2),name="CompFile") t1.start() self.m_staticText4.SetLabelText('正在比较文件请稍后!...') #CompFile(self,file1,file2) def OnClear(self,event): self.m_staticText4.SetForegroundColour(wx.Colour(0,0,0)) self.m_staticText4.SetLabelText('文件比较结果:') self.m_textCtrl3.SetValue('') self.m_textCtrl4.SetValue('') self.m_button4.SetFocus() self.m_button4.SetDefault() def onClose(self,e): self.Destroy() app=wx.App() Mywin(None,'文件比较') app.MainLoop()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值