吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1200|回复: 7
上一主题 下一主题
收起左侧

[Python 原创] 160行代码实现文件检查器(GUI)

  [复制链接]
跳转到指定楼层
楼主
昔年科技 发表于 2024-9-6 14:19 回帖奖励
本帖最后由 昔年科技 于 2024-9-6 14:30 编辑

Python初学者,还望大佬多多指点!

正文
工作中,每个月都会对数据进行汇总,想要方便一些,就写了一个文件校验器。
不同于市面上常见的批量重命名,这个具有自动校验功能,可以检验文件名的连续性,会提示缺失的文件,同时,还会校验文件数量,MD5值,路径等。

功能
1.快速批量校验MD5值校验。
2.文件大小、文件路径显示
3.文件日期连续性校验,对缺失日期文件进行提示。(不完善)
4.搜索框支持中文搜索
5.对小于<10KB的文件会提示异常文件。方便快速定位异常文件
以下是界面截图&源代码&打包文件
1.界面及功能截图

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[i]).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

免费评分

参与人数 3吾爱币 +9 热心值 +3 收起 理由
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
xlln + 1 + 1 我很赞同!
helian147 + 1 + 1 热心回复!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

沙发
mytomsummer 发表于 2024-9-6 15:15
感谢分享学习了
3#
zlqhysy 发表于 2024-9-6 19:55
4#
taokuo 发表于 2024-9-7 00:30
5#
angelicryil 发表于 2024-9-7 07:38
感谢大佬分享
6#
AuroraVerses 发表于 2024-9-7 22:41
感谢分享
7#
jellycici 发表于 2024-9-8 01:05
日常工作有用,谢谢
8#
a761199721 发表于 2024-9-13 09:20
本帖最后由 a761199721 于 2024-9-13 09:31 编辑

1.文件过多时候,没有滚动条,不是很方便查看
2.界面好像就显示330条就不显示了,也不提示完成。。。
运行了下源码,报错了
Traceback (most recent call last):
  File "C:\Users\swu\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1892, in __call__
    return self.func(*args)
  File "G:\Python\python_Project\图片处理\4_文件校验\文件校验.py", line 119, in verify_files
    file_size = os.path.getsize(file_path)
  File "C:\Users\swu\AppData\Local\Programs\Python\Python39\lib\genericpath.py", line 50, in getsize
    return os.stat(filename).st_size
OSError: [WinError 1392] 文件或目录损坏且无法读取。: 'H:/DCIM/100MEDIA\\SYFW00325.jpg'
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-15 01:47

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表