使用Python打造一個(gè)強(qiáng)大的文件分析工具
在日常工作中,我們經(jīng)常需要分析文件夾中的文件分布情況,例如文件類型、文件大小分布以及文件的修改時(shí)間等。手動(dòng)統(tǒng)計(jì)這些信息費(fèi)時(shí)費(fèi)力,因此開(kāi)發(fā)一個(gè)自動(dòng)化工具可以大大提高效率。本文將介紹一個(gè)基于 Python 和 wxPython 開(kāi)發(fā)的圖形化文件分析工具,能夠快速分析文件夾并生成詳細(xì)的統(tǒng)計(jì)報(bào)告。
完整代碼
import wx import os import csv import datetime import subprocess import sys from collections import defaultdict import uuid class FileAnalyzerFrame(wx.Frame): def __init__(self): super().__init__(None, title="File Analyzer", size=(800, 600)) # Create main panel self.panel = wx.Panel(self) main_sizer = wx.BoxSizer(wx.VERTICAL) # Folder selection section folder_sizer = wx.BoxSizer(wx.HORIZONTAL) self.folder_text = wx.TextCtrl(self.panel, size=(400, -1)) browse_button = wx.Button(self.panel, label="Browse...") analyze_button = wx.Button(self.panel, label="Analyze") folder_sizer.Add(wx.StaticText(self.panel, label="Folder: "), 0, wx.ALIGN_CENTER_VERTICAL, 5) folder_sizer.Add(self.folder_text, 1, wx.EXPAND | wx.ALL, 5) folder_sizer.Add(browse_button, 0, wx.ALL, 5) folder_sizer.Add(analyze_button, 0, wx.ALL, 5) # Output file section output_sizer = wx.BoxSizer(wx.HORIZONTAL) self.output_text = wx.TextCtrl(self.panel, size=(400, -1)) self.output_text.SetValue("analysis_results") output_sizer.Add(wx.StaticText(self.panel, label="Output Base Name: "), 0, wx.ALIGN_CENTER_VERTICAL, 5) output_sizer.Add(self.output_text, 1, wx.EXPAND | wx.ALL, 5) # Analysis results results_label = wx.StaticText(self.panel, label="Analysis Results:") self.results_text = wx.TextCtrl(self.panel, style=wx.TE_MULTILINE | wx.TE_READONLY, size=(-1, 200)) # Command execution section cmd_label = wx.StaticText(self.panel, label="Command Editor:") self.cmd_text = wx.TextCtrl(self.panel, size=(-1, 100), style=wx.TE_MULTILINE) execute_button = wx.Button(self.panel, label="Execute Command") # Command output cmd_output_label = wx.StaticText(self.panel, label="Command Output:") self.cmd_output = wx.TextCtrl(self.panel, style=wx.TE_MULTILINE | wx.TE_READONLY, size=(-1, 100)) # Add components to main sizer main_sizer.Add(folder_sizer, 0, wx.EXPAND | wx.ALL, 5) main_sizer.Add(output_sizer, 0, wx.EXPAND | wx.ALL, 5) main_sizer.Add(results_label, 0, wx.ALL, 5) main_sizer.Add(self.results_text, 1, wx.EXPAND | wx.ALL, 5) main_sizer.Add(cmd_label, 0, wx.ALL, 5) main_sizer.Add(self.cmd_text, 0, wx.EXPAND | wx.ALL, 5) main_sizer.Add(execute_button, 0, wx.ALL, 5) main_sizer.Add(cmd_output_label, 0, wx.ALL, 5) main_sizer.Add(self.cmd_output, 1, wx.EXPAND | wx.ALL, 5) self.panel.SetSizer(main_sizer) # Bind events browse_button.Bind(wx.EVT_BUTTON, self.on_browse) analyze_button.Bind(wx.EVT_BUTTON, self.on_analyze) execute_button.Bind(wx.EVT_BUTTON, self.on_execute_command) # Set default properties self.folder_path = "" # Show window self.Centre() self.Show() def on_browse(self, event): """Open folder browser dialog""" dialog = wx.DirDialog(self, "Choose a directory:", style=wx.DD_DEFAULT_STYLE) if dialog.ShowModal() == wx.ID_OK: self.folder_path = dialog.GetPath() self.folder_text.SetValue(self.folder_path) dialog.Destroy() def on_analyze(self, event): """Analyze the selected folder and generate three CSV files""" folder_path = self.folder_text.GetValue() output_base = self.output_text.GetValue() if not folder_path or not os.path.isdir(folder_path): wx.MessageBox("Please select a valid folder.", "Error", wx.OK | wx.ICON_ERROR) return # Generate output file paths file_types_path = f"{output_base}_file_types.csv" size_dist_path = f"{output_base}_size_distribution.csv" month_stats_path = f"{output_base}_year_month.csv" try: # Initialize statistics dictionaries file_type_stats = defaultdict(int) file_size_stats = { "0-10KB": 0, "10KB-100KB": 0, "100KB-1MB": 0, "1MB-10MB": 0, "10MB-100MB": 0, "100MB+": 0 } file_month_stats = defaultdict(int) total_count = 0 total_size = 0 # Create result message result_msg = f"Analyzing folder: {folder_path}\n\n" # Walk through the directory for root, dirs, files in os.walk(folder_path): for file in files: file_path = os.path.join(root, file) try: # Get file extension _, extension = os.path.splitext(file) extension = extension.lower() if not extension: extension = "(no extension)" # Get file size size = os.path.getsize(file_path) total_size += size # Categorize by size if size < 10 * 1024: # < 10KB file_size_stats["0-10KB"] += 1 elif size < 100 * 1024: # < 100KB file_size_stats["10KB-100KB"] += 1 elif size < 1024 * 1024: # < 1MB file_size_stats["100KB-1MB"] += 1 elif size < 10 * 1024 * 1024: # < 10MB file_size_stats["1MB-10MB"] += 1 elif size < 100 * 1024 * 1024: # < 100MB file_size_stats["10MB-100MB"] += 1 else: # >= 100MB file_size_stats["100MB+"] += 1 # Get file modification date mod_time = os.path.getmtime(file_path) dt = datetime.datetime.fromtimestamp(mod_time) month_year = dt.strftime("%Y-%m") # Update statistics file_type_stats[extension] += 1 file_month_stats[month_year] += 1 total_count += 1 except (IOError, OSError) as e: # Skip files that can't be accessed continue # Generate report result_msg += f"Total files: {total_count}\n" result_msg += f"Total size: {self.format_size(total_size)}\n\n" # Write to separate CSV files # 1. File Types CSV with open(file_types_path, 'w', newline='', encoding='utf-8') as csvfile: csv_writer = csv.writer(csvfile) csv_writer.writerow(["Statistics by File Type"]) csv_writer.writerow(["Extension", "Count"]) sorted_types = sorted(file_type_stats.items(), key=lambda x: x[1], reverse=True) for ext, count in sorted_types: csv_writer.writerow([ext, count]) # 2. Size Distribution CSV with open(size_dist_path, 'w', newline='', encoding='utf-8') as csvfile: csv_writer = csv.writer(csvfile) csv_writer.writerow(["Statistics by File Size"]) csv_writer.writerow(["Size Range", "Count"]) for size_range, count in file_size_stats.items(): csv_writer.writerow([size_range, count]) # 3. Year-Month Statistics CSV with open(month_stats_path, 'w', newline='', encoding='utf-8') as csvfile: csv_writer = csv.writer(csvfile) csv_writer.writerow(["Statistics by Month"]) csv_writer.writerow(["Month", "Count"]) sorted_months = sorted(file_month_stats.items()) for month, count in sorted_months: csv_writer.writerow([month, count]) # Show file types in result result_msg += "File types (Top 10):\n" for ext, count in sorted_types[:10]: result_msg += f"{ext}: {count} files\n" result_msg += "\nSize distribution:\n" for size_range, count in file_size_stats.items(): result_msg += f"{size_range}: {count} files\n" result_msg += "\nAnalysis completed successfully!\n" result_msg += f"CSV reports saved to:\n" result_msg += f"- {file_types_path}\n" result_msg += f"- {size_dist_path}\n" result_msg += f"- {month_stats_path}" # Update results text self.results_text.SetValue(result_msg) except Exception as e: wx.MessageBox(f"An error occurred: {str(e)}", "Error", wx.OK | wx.ICON_ERROR) def on_execute_command(self, event): """Execute the command in the command editor""" command = self.cmd_text.GetValue().strip() if not command: wx.MessageBox("Please enter a command to execute.", "Error", wx.OK | wx.ICON_ERROR) return try: # Create a new process, capture output process = subprocess.Popen( command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True ) # Get the output stdout, stderr = process.communicate() # Display output output = "" if stdout: output += stdout if stderr: output += "\nErrors:\n" + stderr self.cmd_output.SetValue(output) except Exception as e: self.cmd_output.SetValue(f"Error executing command: {str(e)}") def format_size(self, size_in_bytes): """Format file size to human-readable format""" for unit in ['B', 'KB', 'MB', 'GB', 'TB']: if size_in_bytes < 1024.0 or unit == 'TB': return f"{size_in_bytes:.2f} {unit}" size_in_bytes /= 1024.0 def main(): app = wx.App() frame = FileAnalyzerFrame() app.MainLoop() if __name__ == "__main__": main()
工具功能概覽
這個(gè)文件分析工具提供以下核心功能:
1.文件夾選擇:通過(guò)圖形界面選擇需要分析的文件夾。
2.文件統(tǒng)計(jì)分析:
- 按文件擴(kuò)展名統(tǒng)計(jì)文件數(shù)量。
- 按文件大小區(qū)間(如 0-10KB、10KB-100KB 等)統(tǒng)計(jì)文件分布。
- 按文件修改時(shí)間的年月統(tǒng)計(jì)文件數(shù)量。
3.CSV 報(bào)告生成:將分析結(jié)果保存為三個(gè)獨(dú)立的 CSV 文件,分別記錄文件類型、大小分布和年月統(tǒng)計(jì)。
4.命令執(zhí)行器:提供一個(gè)簡(jiǎn)單的命令行界面,允許用戶在工具中執(zhí)行系統(tǒng)命令并查看輸出。
5.人性化界面:通過(guò) wxPython 構(gòu)建直觀的圖形界面,方便用戶操作。
技術(shù)棧
Python:核心編程語(yǔ)言,用于文件操作和數(shù)據(jù)處理。
wxPython:用于構(gòu)建跨平臺(tái)的圖形用戶界面。
os 和 datetime:用于文件系統(tǒng)操作和時(shí)間處理。
csv:用于生成 CSV 格式的報(bào)告。
subprocess:用于執(zhí)行系統(tǒng)命令。
collections.defaultdict:簡(jiǎn)化統(tǒng)計(jì)數(shù)據(jù)結(jié)構(gòu)的處理。
uuid:用于生成唯一標(biāo)識(shí)符(本例中未直接使用,但代碼中引入)。
代碼結(jié)構(gòu)分析
以下是工具的核心代碼結(jié)構(gòu)和功能解析:
1. 圖形界面設(shè)計(jì)
工具使用 wxPython 構(gòu)建了一個(gè)直觀的窗口,包含以下組件:
- 文件夾選擇區(qū)域:包含文本框和“瀏覽”按鈕,用于選擇分析的文件夾。
- 輸出文件名設(shè)置:允許用戶指定輸出 CSV 文件的基礎(chǔ)名稱。
- 分析結(jié)果顯示:一個(gè)多行只讀文本框,用于顯示分析結(jié)果摘要。
- 命令編輯器:允許用戶輸入系統(tǒng)命令并執(zhí)行,執(zhí)行結(jié)果顯示在另一個(gè)只讀文本框中。
界面通過(guò) wx.BoxSizer 進(jìn)行布局,確保組件排列整齊且自適應(yīng)窗口大小調(diào)整。
2. 文件分析邏輯
文件分析功能由 on_analyze 方法實(shí)現(xiàn),具體步驟如下:
1.輸入驗(yàn)證:檢查用戶是否選擇了有效文件夾。
2.統(tǒng)計(jì)初始化:
- 使用 defaultdict 記錄文件類型統(tǒng)計(jì)。
- 定義文件大小區(qū)間字典(如 0-10KB、10KB-100KB 等)。
- 使用 defaultdict 記錄按年月統(tǒng)計(jì)的文件數(shù)量。
3.文件夾遍歷:通過(guò) os.walk 遞歸遍歷文件夾,獲取每個(gè)文件的擴(kuò)展名、大小和修改時(shí)間。
4.數(shù)據(jù)處理:
- 文件擴(kuò)展名統(tǒng)計(jì):提取文件擴(kuò)展名并計(jì)數(shù)。
- 文件大小分類:根據(jù)文件大小歸類到對(duì)應(yīng)區(qū)間。
- 修改時(shí)間統(tǒng)計(jì):將文件修改時(shí)間格式化為“年-月”并計(jì)數(shù)。
5.報(bào)告生成:
- 生成三個(gè) CSV 文件,分別記錄文件類型、大小分布和年月統(tǒng)計(jì)。
- 在界面上顯示分析摘要,包括文件總數(shù)、總大小、文件類型前十、文件大小分布等。
3. 命令執(zhí)行功能
命令執(zhí)行功能由 on_execute_command 方法實(shí)現(xiàn),允許用戶輸入系統(tǒng)命令(如 dir 或 ls)并查看輸出:
- 使用 subprocess.Popen 執(zhí)行命令,捕獲標(biāo)準(zhǔn)輸出和錯(cuò)誤輸出。
- 將執(zhí)行結(jié)果顯示在界面上的命令輸出文本框中。
- 包含錯(cuò)誤處理,確保命令執(zhí)行失敗時(shí)顯示友好提示。
4. 輔助功能
文件大小格式化:format_size 方法將字節(jié)大小轉(zhuǎn)換為人類可讀的格式(如 KB、MB、GB)。
錯(cuò)誤處理:工具在文件訪問(wèn)、分析和命令執(zhí)行過(guò)程中都包含了異常捕獲,確保程序穩(wěn)定性。
使用方法
運(yùn)行程序:
- 確保安裝了 Python 和 wxPython(pip install wxPython)。
- 保存代碼為 file_analyzer.py 并運(yùn)行。
選擇文件夾:
點(diǎn)擊“Browse”按鈕選擇需要分析的文件夾。
設(shè)置輸出文件名:
在“Output Base Name”文本框中輸入 CSV 文件的基礎(chǔ)名稱(默認(rèn)為 analysis_results)。
執(zhí)行分析:
點(diǎn)擊“Analyze”按鈕,工具將分析文件夾并生成三個(gè) CSV 文件,同時(shí)在界面上顯示結(jié)果摘要。
執(zhí)行命令:
在命令編輯器中輸入系統(tǒng)命令,點(diǎn)擊“Execute Command”查看輸出。
示例輸出
假設(shè)分析一個(gè)包含多種文件的文件夾,工具將生成以下 CSV 文件:
analysis_results_file_types.csv:
Statistics by File Type
Extension,Count
.txt,50
.jpg,30
.pdf,20
(no extension),10
...
analysis_results_size_distribution.csv:
Statistics by File Size
Size Range,Count
0-10KB,60
10KB-100KB,30
100KB-1MB,15
1MB-10MB,5
10MB-100MB,0
100MB+,0
analysis_results_year_month.csv:
Statistics by Month
Month,Count
2023-01,20
2023-02,30
2024-01,40
...
界面上的結(jié)果摘要可能如下:
Analyzing folder: /path/to/folder
Total files: 110
Total size: 1.23 GB
File types (Top 10):
.txt: 50 files
.jpg: 30 files
.pdf: 20 files
(no extension): 10 files
...
Size distribution:
0-10KB: 60 files
10KB-100KB: 30 files
...
Analysis completed successfully!
CSV reports saved to:
- analysis_results_file_types.csv
- analysis_results_size_distribution.csv
- analysis_results_year_month.csv
運(yùn)行結(jié)果
到此這篇關(guān)于使用Python打造一個(gè)強(qiáng)大的文件分析工具的文章就介紹到這了,更多相關(guān)Python文件分析內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
用pushplus+python監(jiān)控亞馬遜到貨動(dòng)態(tài)推送微信
這篇文章主要介紹了用pushplus+python監(jiān)控亞馬遜到貨動(dòng)態(tài)推送微信的示例,幫助大家利用python搶購(gòu)商品,感興趣的朋友可以了解下2021-01-01利用Pytorch實(shí)現(xiàn)獲取特征圖的方法詳解
這篇文章主要為大家詳細(xì)介紹了如何利用Pytorch實(shí)現(xiàn)獲取特征圖,包括提取單個(gè)特征圖和提取多個(gè)特征圖,文中的示例代碼講解詳細(xì),需要的可以參考一下2022-10-10通過(guò)python爬蟲(chóng)mechanize庫(kù)爬取本機(jī)ip地址的方法
python中的mechanize算是一個(gè)比較古老的庫(kù)了,在python2的時(shí)代中,使用的多一些,在python3以后就很少使用了,現(xiàn)在已經(jīng)是2202年了,可能很多人都沒(méi)聽(tīng)說(shuō)過(guò)mechanize,這不要緊,我們先來(lái)簡(jiǎn)單的講解一下,如何使用mechanize,感興趣的朋友一起看看吧2022-08-08python基于Tkinter實(shí)現(xiàn)人員管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了python基于Tkinter實(shí)現(xiàn)人員管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11Django 解決上傳文件時(shí),request.FILES為空的問(wèn)題
這篇文章主要介紹了Django 解決上傳文件時(shí),request.FILES為空的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-05-05Scrapy爬蟲(chóng)實(shí)例講解_?;ňW(wǎng)
下面小編就為大家?guī)?lái)一篇Scrapy爬蟲(chóng)實(shí)例講解_校花網(wǎng)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-10-10