160行代码实现文件检查器(GUI)

查看 54|回复 3
作者:昔年科技   
Python初学者,还望大佬多多指点!
正文
工作中,每个月都会对数据进行汇总,想要方便一些,就写了一个文件校验器。
不同于市面上常见的批量重命名,这个具有自动校验功能,
[color=]可以检验文件名的连续性
,会提示缺失的文件,同时,还会校验文件数量,MD5值,路径等。
功能
1.快速批量校验MD5值校验。
2.文件大小、文件路径显示
3.文件日期连续性校验,对缺失日期文件进行提示。(不完善)
4.搜索框支持中文搜索
5.对小于。方便快速定位异常文件
以下是界面截图&源代码&打包文件
1.界面及功能截图


1725602252954.jpg (213.33 KB, 下载次数: 0)
下载附件
界面
2024-9-6 13:57 上传

2.源代码
[Python] 纯文本查看 复制代码import os
import tkinter as tk
from tkinter import filedialog, messagebox, ttk
from datetime import datetime
import hashlib
import math
import re
class FileVerifier:
    def __init__(self, master):
        self.master = master
        master.title("文件校验")
        self.folder_path = tk.StringVar()
        self.filter_rule = tk.StringVar()
        self.create_widgets()
        self.tree = self.create_treeview()
        self.context_menu = self.create_context_menu()
        self.file_paths = {}
    def create_widgets(self):
        # 使用Frame来组织并集中管理其他所有Widget
        self.main_frame = tk.Frame(self.master)
        self.main_frame.pack(fill=tk.BOTH, expand=True)
        tk.Label(self.main_frame, text="文件夹路径:").grid(row=0, column=0, sticky="w")
        # 增加sticky参数以确保控件填满单元格并左对齐
        tk.Entry(self.main_frame, textvariable=self.folder_path).grid(row=0, column=1, sticky="we")
        tk.Button(self.main_frame, text="浏览", command=self.select_folder).grid(row=0, column=2, sticky="e")
        tk.Label(self.main_frame, text="文件名匹配规则:").grid(row=1, column=0, sticky="w")
        tk.Entry(self.main_frame, textvariable=self.filter_rule).grid(row=1, column=1, sticky="we")
        tk.Button(self.main_frame, text="开始校验", command=self.verify_files).grid(row=1, column=2, sticky="e")
    def create_treeview(self):
        columns = ('status', 'filename', 'size', 'modified', 'md5', 'path')
        tree = ttk.Treeview(self.master, columns=columns, show='headings')
        scrollbar = ttk.Scrollbar(self.master, orient=tk.VERTICAL, command=tree.yview)
        tree.configure(yscrollcommand=scrollbar.set)
        for col in columns:
            tree.heading(col, text=col.capitalize())
            tree.column(col, width=100)
        tree.pack(fill=tk.BOTH, expand=True)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        return tree
    def create_context_menu(self):
        context_menu = tk.Menu(self.master, tearoff=0)
        context_menu.add_command(label="打开文件", command=self.open_file)
        context_menu.add_command(label="在 Windows 资源管理器中打开", command=self.open_file_in_explorer)
        return context_menu
    def select_folder(self):
        folder_selected = filedialog.askdirectory()
        if folder_selected:
            self.folder_path.set(folder_selected)
    def show_context_menu(self, event):
        # 获取选中的项
        iid = self.tree.identify_row(event.y)
        if iid:
            self.tree.selection_set(iid)
            self.context_menu.post(event.x_root, event.y_root)
    def open_file(self):
        selected_item = self.tree.selection()
        if selected_item:
            file_path = self.file_paths[selected_item[0]]
            if os.path.isfile(file_path):
                os.startfile(file_path)
    def open_file_in_explorer(self):
        selected_item = self.tree.selection()
        if selected_item:
            file_path = self.file_paths[selected_item[0]]
            file_dir = os.path.dirname(file_path)
            os.startfile(file_dir)
    def get_file_size(self, size):
        if size >= 1024 * 1024:
            return f"{size / (1024 * 1024):.2f} MB"
        elif size >= 1024:
            return f"{size / 1024:.2f} KB"
        else:
            return f"{size} B"
    def calculate_md5(self, filename):
        hash_md5 = hashlib.md5()
        with open(filename, "rb") as f:
            for chunk in iter(lambda: f.read(4096), b""):
                hash_md5.update(chunk)
        return hash_md5.hexdigest()
    def verify_files(self):
        folder_path = self.folder_path.get()
        filter_rule = self.filter_rule.get()
        if not folder_path:
            messagebox.showerror("错误", "请选择文件夹路径!")
            return
        if not filter_rule:
            messagebox.showerror("错误", "请输入文件名匹配规则!")
            return
        file_count = 0
        self.tree.delete(*self.tree.get_children())  # 清空Treeview
        self.file_paths.clear()  # 清空文件路径字典
        for root, dirs, files in os.walk(folder_path):
            for name in files:
                if filter_rule in name:
                    file_path = os.path.join(root, name)
                    file_size = os.path.getsize(file_path)
                    file_size_str = self.get_file_size(file_size)
                    modification_time = os.path.getmtime(file_path)
                    formatted_modification_time = datetime.fromtimestamp(modification_time).strftime('%Y-%m-%d %H:%M:%S')
                    md5 = self.calculate_md5(file_path)
                    status = "Ok" if file_size >= 10 * 1024 else "异常文件"
                    self.tree.insert('', tk.END, values=(status, name, file_size_str, formatted_modification_time, md5, file_path))
                    self.file_paths[self.tree.get_children()[-1]] = file_path
                    file_count += 1
        self.master.update_idletasks()
        self.master.minsize(self.tree.winfo_width(), self.tree.winfo_height())
        messagebox.showinfo("完成", f"校验完成。共找到 {file_count} 个文件。")
        self.check_file_date_continuity(files)
    def check_file_date_continuity(self, file_list):
        date_list = []
        missing_dates = []
        for file_name in file_list:
            match = re.search(r'\d{8}', file_name)
            if match:
                date_str = match.group()
                date = datetime.strptime(date_str, '%Y%m%d')
                date_list.append(date)
        date_list.sort()
        for i in range(len(date_list) - 1):
            if (date_list[i + 1] - date_list).days > 1:
                missing_dates.append(date_list[i + 1])
        if missing_dates:
            message = "以下日期的文件缺失:\n"
            for date in missing_dates:
                message += f"{date.strftime('%Y-%m-%d')}\n"
            messagebox.showwarning("警告", message)
        else:
            messagebox.showinfo("通知", "文件名日期连续,没有缺失。")
if __name__ == "__main__":
    root = tk.Tk()
    app = FileVerifier(root)
    root.mainloop()
打包好的EXE(不放心的,可以审查源码。打包只是方便使用)
virscan检测报告:https://www.virscan.org/report/aaf8c24604039827cd9b95a40550b893a01052a61b85469dfd6d051ee0f80533
蓝奏:https://wwi.lanzoup.com/iYcdr29c201c       密码:52pj

文件, 路径

mytomsummer   

感谢分享学习了
zlqhysy   

感谢分享
taokuo   

感谢分享
您需要登录后才可以回帖 登录 | 立即注册

返回顶部