python制作的一个exe程序——文件对比增量包

指定两个目录下的文件对比工具

1、业务需求
a、一般的web项目实际上tomcat服务器运行的java
class、前端js、一些静态资源等组成,不同项目间的对应目录自然文件不一样,同一个项目的不同版本即升级之间也是新增或修改了部分文件,那升级安装或是在线升级的功能实现也就是下载或手动替换掉有变动的文件
b、上一种方式的增量升级,包文件少,在线升级不影响当前应用,web服务也可以把增量文件替换后自动重启运行,还能运用到的一种场景就是maven的本地库的依赖添加,前端nodemodule的js依赖库添加,这些大型目录下的文件动辄10G以上,往往其他地方能正常运行的单个项目依赖不必全部拷贝过来,增量添加即可

2、工具实现
方便易用肯定先想到的是制作成exe程序,单击即用,目前python集成windows下的打包桌面程序也是异常的方便

先看成品GUI界面
在这里插入图片描述
UI样式就不计较了,只为了实现功能,简单的tkinter界面工具
文末给出该工具链接

source:旧版本目录、少文件目录、或者说需要升级的目录
生成对比文件目录:记录旧版本目录的文件结构,可勾选md5文件内容对比,会生成一个文本文件
target:目标目录,多文件目录,或者说最新版本的对比目录
source!:生成对比文件按钮
started!:生成增量文件按钮

对比文件可在两台电脑间运行即对比不同机器间的目录,保持两个目录文件或者是内容(勾选md5)一致,

这也是此工具最终目的:生成两个目录(可跨电脑)下所有文件的差集(包含目录结构,方便直接拖拽进去,使得两个目录下的文件及内容一模一样)

  • 开发环境(python:3.7.3、pyinstaller:3.6)
  • 代码如下
import hashlib
import tkinter
import tkinter.messagebox
import shutil
import ast
from tkinter.filedialog import *


def get_all_files(base, files_, check):
    if not os.path.exists(base):
        tkinter.messagebox.showerror("error", '系统source路径不存在!')
        return
    list_ = os.listdir(base)
    for i in range(0, len(list_)):
        path = os.path.join(base, list_[i])
        if os.path.isdir(path):
            get_all_files(path, files_, check)
        if os.path.isfile(path):
            if check == 1:
                files_.append(get_file_md5(path))
            else:
                files_.append(path)
    return files_


def get_file_md5(filename):
    h = hashlib.md5()
    f = open(filename, 'rb')
    while True:
        b = f.read(8096)
        if not b:
            break
        h.update(b)
    f.close()
    return h.hexdigest()


def write(files, path):
    a = open(path, 'w', encoding="utf-8")
    a.write(files)
    a.close()  # 完成存储


def read(path):
    if not os.path.exists(path):
        tkinter.messagebox.showwarning("error", '桌面不存在对比文件' + path)
        return
    a = open(path, 'r', encoding="utf-8")
    files = ast.literal_eval(a.read())
    a.close()
    return files


def list2file(base, path, check):
    files = get_all_files(base, [base], check)
    value = str(files)
    write(value, path)
    if not os.path.exists(os.path.dirname(path)):
        os.makedirs(os.path.dirname(path))
    tkinter.messagebox.showinfo('生成桌面文件:', path)


def produce(target, path, outpath, check):
    if not len(target) > 0 or not len(target) > 0:
        tkinter.messagebox.showerror("error", '目标文件目录不能为空!')
        return
    source_list = read(path)
    target_list = get_all_files(target, [], 0)
    source = source_list[0]
    for i in range(0, len(target_list)):
        compare = target_list[i].replace(target, source, 1)
        md5 = get_file_md5(target_list[i])
        if check == 0 and compare not in source_list:
            if not os.path.exists(outpath):
                os.makedirs(outpath)
            path_ = os.path.dirname((target_list[i])).replace(target, outpath, 1)
            if not os.path.exists(path_):
                os.makedirs(path_)
            shutil.copy(target_list[i], path_)
        elif check == 1 and md5 not in source_list:
            if not os.path.exists(outpath):
                os.makedirs(outpath)
            path_ = os.path.dirname((target_list[i])).replace(target, outpath, 1)
            if not os.path.exists(path_):
                os.makedirs(path_)
            shutil.copy(target_list[i], path_)
        elif check == 0:
            source_list.remove(compare)
        elif check == 1:
            source_list.remove(md5)
    tkinter.messagebox.showinfo("success", "增量包拷贝成功!\r\n("+outpath+")")


def create_gui():

    top = tkinter.Tk()
    top.geometry('770x370+600+400')

    label = tkinter.Label(top, text='source: 原始文件夹    target:目标文件夹 \r\n对比原始和目标文件夹,将目标目录不存在的文件或有修改的文件,生成增量包!\r\n'
                                    'source:生成对比文件     started:生成增量包\r\n check md5是否校验文件内容', fg='red')
    label.grid(row=5)

    Label(top, text="source路径:").grid(row=13)
    Label(top, text="生成对比文件路径:").grid(row=14)
    Label(top, text="target路径:").grid(row=15)
    Label(top, text="生成增量包路径:").grid(row=16)

    e1 = Entry(top, bd=3, relief='groove', width=30, textvariable='请输入source路径')
    e2 = Entry(top, bd=3, relief='groove', width=30, textvariable='生成对比文件路径:')
    check = IntVar(0)
    r1 = Checkbutton(top, text="check md5", onvalue=1, variable=check, offvalue=0, height=5, width=10)
    e3 = Entry(top, bd=3, relief='groove', width=30, textvariable='请输入target路径')
    e4 = Entry(top, bd=3, relief='groove', width=30, textvariable='生成增量包路径:')

    e1.grid(row=13, column=1)
    e2.grid(row=14, column=1)
    r1.grid(row=14, column=2)
    e3.grid(row=15, column=1)
    e4.grid(row=16, column=1)

    Button(top, text='source!', width=30, relief='raised', activeforeground='red', command=lambda: list2file(e1.get(), e2.get(), check.get())).grid(column=0, row=20)
    Button(top, text='started!', width=30, relief='raised', activeforeground='red', command=lambda: produce(e3.get(), e2.get(), e4.get(), check.get())).grid(column=0, row=22)
    top.mainloop()


if __name__ == "__main__":

    create_gui()

导包文件:

  1. hashlib 计算文件的md5值
  2. tkinter 界面GUI
  3. shutil 拷贝文件
  4. ast 字符串转集合

主要方法:

  1. 递归获取文件夹下的所有文件集合,check参数:文件名还是md5值
def get_all_files(base, files_, check):
    if not os.path.exists(base):
        tkinter.messagebox.showerror("error", '系统source路径不存在!')
        return
    list_ = os.listdir(base)
    for i in range(0, len(list_)):
        path = os.path.join(base, list_[i])
        if os.path.isdir(path):
            get_all_files(path, files_, check)
        if os.path.isfile(path):
            if check == 1:
                files_.append(get_file_md5(path))
            else:
                files_.append(path)
    return files_

  1. 将文件名或者是md5集合转为文件输出,此处获取所有文件集合,传了个带base的集合参数,一是递归的时候元素不会重复,二是对比的时候第一个元素是原始对比目录,对比遍历目标所有文件的绝对路径时,替换前面一部分去集合里匹配有没有或者是md5值是否一样
def list2file(base, path, check):
    files = get_all_files(base, [base], check)
    value = str(files)
    write(value, path)
    if not os.path.exists(os.path.dirname(path)):
        os.makedirs(os.path.dirname(path))
    tkinter.messagebox.showinfo('生成桌面文件:', path)
  1. produce方法,主要逻辑生成增量文件到指定的目录
  2. create_gui方法,生成界面,注意控件的pack和grid布局方法
  • 程序测试
    source: C:\Users\Administrator\Desktop\bb目录下有两个文件在这里插入图片描述在这里插入图片描述
    target:C:\Users\Administrator\Desktop\aa 多了个文件夹dir1,dir1里有个cc.txt文件,外层的内容上aa.txt与原始内容不同,bb.txt则文件内容一致
    在这里插入图片描述
    在这里插入图片描述
    运行界面生成对比文件campare.txt:
    在这里插入图片描述
    我们把生成增量包路径放置桌面cc文件夹,配置上对比文件路径campare.txt(该文件可从另一台电脑上生成),点击started
    在这里插入图片描述
    最后查看下生成的桌面cc文件夹
    在这里插入图片描述
    携带了dir1目录及下面的cc.txt文件,文件内容不一致的aa.txt也是target目录的aa文本内容的文件
    在这里插入图片描述
    所有程序的代码文章已给出,打exe程序python需要安装pyinstaller包(pip install PyInstaller),执行一下命令即可:pyinstaller -F -w -i ico路径 varCode_addFile.py

赋上程序连接:

链接:https://pan.baidu.com/s/1qsbUcSmsZw-EWZFAjGWttg
提取码:vqzz

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值