在处理历史文件或与不同系统交互时,我们经常会遇到 GBK 或 GB2312 编码的文本文件。虽然现在 UTF-8 是主流,但手动转换这些旧编码文件既繁琐又容易出错。为了解决这个问题,我开发了一个简单的图形界面工具,可以批量将指定文件夹下的 GBK/GB2312 文件转换为 UTF-8 编码。
这个工具使用 Python 和 Tkinter 构建,提供了一个直观的用户界面。它具备以下主要功能:
chardet
库自动识别文件编码,并针对 GBK/GB2312 做了优化处理。您可以选择以下两种方式之一来使用该工具:
pip install -r requirements.txt
python main.py
.exe
文件)。以下是工具的主要 Python 源代码 (main.py
):
import tkinter as tk
from tkinter import filedialog, messagebox, scrolledtext
import os
import chardet
import threading
import webbrowser # ", self.open_link)
# 配置行列权重,使控件随窗口缩放
master.grid_rowconfigure(3, weight=1) # 日志区域占满剩余空间
master.grid_rowconfigure(4, weight=0) # 链接行不扩展
master.grid_columnconfigure(1, weight=1)
def log(self, message):
"""向日志区域添加消息"""
self.log_text.config(state=tk.NORMAL)
self.log_text.insert(tk.END, message + "n")
self.log_text.see(tk.END) # 滚动到底部
self.log_text.config(state=tk.DISABLED)
self.master.update_idletasks() # 强制更新界面
def browse_folder(self):
"""打开文件夹选择对话框"""
folder_selected = filedialog.askdirectory()
if folder_selected:
self.folder_path_var.set(folder_selected)
self.log(f"已选择文件夹: {folder_selected}")
def is_text_file(self, filename):
"""根据扩展名判断是否可能是文本或代码文件"""
_, ext = os.path.splitext(filename)
return ext.lower() in TEXT_FILE_EXTENSIONS
def detect_encoding(self, file_path):
"""检测文件编码"""
try:
with open(file_path, 'rb') as f:
raw_data = f.read(4096) # 读取一部分数据进行检测
result = chardet.detect(raw_data)
encoding = result['encoding']
confidence = result['confidence']
# chardet有时会将GBK/GB2312检测为其他编码,增加一些兼容性判断
if encoding and encoding.lower() in ['gb2312', 'gbk', 'gb18030']:
return encoding.lower(), confidence
# 对于置信度不高的常见误判,也尝试按GBK处理
if encoding and confidence {TARGET_ENCODING})")
return True
else:
self.log(f"跳过: {os.path.basename(file_path)} (已经是 {TARGET_ENCODING} 或无需转换)")
return False
except Exception as e:
self.log(f"转换失败: {os.path.basename(file_path)} - {e}")
return False
def process_folder(self, folder_path):
"""处理指定文件夹下的所有文件"""
converted_count = 0
skipped_count = 0
error_count = 0
processed_files = 0
self.log(f"n开始扫描文件夹: {folder_path}")
for root, _, files in os.walk(folder_path):
for filename in files:
if not self.is_text_file(filename):
# self.log(f"忽略非文本文件: {filename}")
continue
file_path = os.path.join(root, filename)
processed_files += 1
self.log(f"正在处理: {file_path}")
encoding, confidence = self.detect_encoding(file_path)
if encoding and encoding.lower() in SUPPORTED_ENCODINGS:
self.log(f"检测到 {encoding.upper()} (置信度: {confidence:.2f}): {filename}")
if self.convert_file_encoding(file_path, encoding):
converted_count += 1
else:
error_count += 1
elif encoding:
# self.log(f"跳过 (非GBK/GB2312编码: {encoding}): {filename}")
skipped_count += 1
else:
# self.log(f"跳过 (无法检测编码): {filename}")
skipped_count += 1
error_count += 1 # 无法检测也算一种错误
self.log(f"n处理完成。共扫描 {processed_files} 个文本/代码文件。")
self.log(f"成功转换: {converted_count}")
self.log(f"跳过文件: {skipped_count}")
self.log(f"转换/检测失败: {error_count}")
messagebox.showinfo("完成", f"转换完成!n成功: {converted_count}n跳过: {skipped_count}n失败: {error_count}")
# 转换完成后重新启用按钮
self.convert_button.config(state=tk.NORMAL)
self.browse_button.config(state=tk.NORMAL)
def start_conversion_thread(self):
"""在单独的线程中开始转换过程,避免GUI卡死"""
folder_path = self.folder_path_var.get()
if not folder_path or not os.path.isdir(folder_path):
messagebox.showerror("错误", "请先选择一个有效的文件夹!")
return
# 禁用按钮,防止重复点击
self.convert_button.config(state=tk.DISABLED)
self.browse_button.config(state=tk.DISABLED)
self.log_text.config(state=tk.NORMAL)
self.log_text.delete('1.0', tk.END) # 清空日志
self.log_text.config(state=tk.DISABLED)
# 创建并启动线程
conversion_thread = threading.Thread(target=self.process_folder, args=(folder_path,), daemon=True)
conversion_thread.start()
def open_link(self, event):
"""打开GitHub链接"""
webbrowser.open_new(self.github_url)
if __name__ == "__main__":
root = tk.Tk()
app = EncodingConverterApp(root)
root.mainloop()
如果您对这个工具感兴趣,或者想查看完整的项目代码和构建说明,请访问项目的 GitHub 仓库:
https://github.com/dependon/gbk2utf8
希望这个小工具能对您有所帮助!
本文由博客一文多发平台 OpenWrite 发布!
参与评论
手机查看
返回顶部