PyPDF2加密大PDF时pdfWriter.write无报错挂起问题求助
问题根因及修复方案
触发挂起的核心原因
- 冗余循环逻辑错误:
os.walk返回的files已经是当前目录下的所有文件,额外嵌套的for subfolder in subfolders层会导致同一份文件列表被重复遍历N次(N为当前目录子文件夹数量),大文件场景下重复IO操作直接导致进程阻塞 - 文件句柄泄漏:读取源PDF、写入目标PDF时均未显式关闭文件对象,大文件场景下IO缓冲区溢出、系统句柄占用超限都会导致写入无响应
- PyPDF2旧版本加密接口缺陷:2.0版本前的
encrypt接口处理大于50M的PDF时,内存占用会飙升至原文件的8~10倍,无响应本质是内存占满后系统在读写虚拟内存
修复后代码
import os import re import PyPDF2 # 正则规则替换为你自己的匹配逻辑 reg = re.compile(r'.*\.pdf$', re.I) root_path = r'C:\Users\xxxx\Downloads' for folder, subfolders, files in os.walk(root_path): # 直接遍历当前目录下的文件,去掉冗余的subfolder循环 for file in files: p = os.path.join(folder, file) filtered = reg.search(file) if filtered is None: continue print(f"处理文件:{p}") # 用with上下文管理器自动关闭文件句柄 with open(p, 'rb') as src_f: # PyPDF2 2.0+版本建议用PdfReader替代废弃的PdfFileReader pdfread = PyPDF2.PdfFileReader(src_f) print(f"总页数:{pdfread.numPages}") pdfWriter = PyPDF2.PdfFileWriter() for pageNum in range(pdfread.numPages): pageObj = pdfread.getPage(pageNum) pdfWriter.addPage(pageObj) pdfWriter.encrypt('xxxxx') # 输出路径拼上原目录,避免所有生成文件都存到脚本运行目录 out_path = os.path.join(folder, f"{os.path.splitext(file)[0]}_encrypted.pdf") with open(out_path, 'wb') as out_f: pdfWriter.write(out_f)
大文件优化建议
如果处理超过100M的PDF仍然卡顿,建议替换PyPDF2为pikepdf库,加密性能是PyPDF2的3倍以上,内存占用仅为前者的1/5。
内容的提问来源于stack exchange,提问作者satya18948
相关产品推荐
相关产品推荐

