对文件或文件夹压缩,是日常工作中经常要做的事情,市面上也有非常多的压缩工具,在linux系统里,有zip, tar等命令可以用于压缩。最近学习了python的zipfile模块,它提供了通用的创建,读取,写入压缩文件的方法,使用方法非常简单,我尝试使用tkinter 写一个简单的压缩小工具。
界面这块,需要一个文件选择框,一个文件选择按钮,一个压缩按钮和一个label用于显示压缩过程中被压缩的文件。
功能方面,不提供对压缩文件命名的能力,只对文件夹进行压缩,压缩后的文件保存在和被压缩文件夹同级的目录中,压缩文件的名称为:文件夹名称.zip。
就这样,开干。
import zipfile
import tkinter as tk
from tkinter import filedialog
from pathlib import Path
window = tk.Tk()
window.title('文件对话框') # 设置窗口的标题
window.geometry('800x100') # 设置窗口的大小
# 输入框
path_var = tk.StringVar()
entry = tk.Entry(window, textvariable=path_var, width=95)
entry.place(x=10, y=10, anchor='nw')
# 压缩明细
compress_var = tk.StringVar()
label = tk.Label(window, textvariable=compress_var, width=100, height=2, anchor='nw')
label.place(x=10, y=30) # 将标签固定在窗口上
tk.Button(window, text='选择').place(x=700, y=10, anchor='nw')
tk.Button(window, text='压缩').place(x=750, y=10, anchor='nw')
window.mainloop()
运行程序,界面效果如下
点击选择按钮时,弹出文件选择对话框,我需要为选择按钮绑定一个函数
def click():
file_name= filedialog.askdirectory(title='选择一个文件夹',
initialdir='./' # 打开当前程序工作目录
)
path_var.set(file_name)
tk.Button(window, text='选择', command=click).place(x=700, y=10, anchor='nw')
选择好文件夹后,文件夹目录会在entry中显示。
def compress():
select_path = path_var.get() # 获取路径
select_path = Path(select_path)
zip_name = select_path.name + ".zip" # 最终的压缩文件路径
zip_path = select_path.parent.joinpath(zip_name)
with zipfile.ZipFile(str(zip_path), 'w')as f: # 进行压缩
files = select_path.glob("**/*") # 遍历被压缩文件的所有目录和文件
for filename in files:
compress_path = filename.relative_to(select_path) # 这里要获得被压缩文件的相对路径
compress_var.set(str(filename)) # 显示被压缩文件
label.update() # 更新label
f.write(str(filename), arcname=compress_path) # 压缩写入
compress_var.set('完成压缩')
label.update()
tk.Button(window, text='压缩', command=compress).place(x=750, y=10, anchor='nw')
压缩的过程很简单,使用zipfile.ZipFile创建压缩文件,然后将想要压缩的文件写入即可。这里容易产生一个误区,假设你想压缩demo文件夹,你以为f.write('/demo') 就可以将demo文件夹压缩好,这是错误的,压缩后的文件夹里,只有一个空的demo文件夹。write方法,如果传入的是文件,则压缩文件,如果传入的是文件夹,它不会默认压缩这个文件夹里的内容,只是会在压缩文件里为你创建这个文件夹而已。
因此,你想压缩某个文件,必须自己去遍历它,把demo目录下的所有文件夹和文件都使用write方法压缩写入才行。使用write方法时,第一个参数是你想要压缩的文件的目录,可以是相对路径,也可以是绝对路径,我这里用的是绝对路径,不能用相对路径,因为相对路径是相对我程序的启动目录而言的,这个路径难以计算。arcname是压缩包里的路径,这里必须用相对路径,是相对于被压缩文件的路径,比如demo目录下有一个1.txt文件,那么写入这个文件时,就应该这样写
f.write("d:/test/demo/1.txt", arcname='1.txt')
对文件的操作,我使用了pathlib模块的Path, 它是最新的文件系统处理模块,意在替换老旧的os.path等模块。
QQ交流群: 211426309