文章目录
-
- 使用方法
-
- [1. **直接修改配置参数**](#1. 直接修改配置参数)
- [2. **运行脚本**](#2. 运行脚本)
- 极简版本(如果只想快速使用)
python
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
批量使用podofogc处理PDF文件 - 简化版
功能:遍历顶级目录及子目录中的所有PDF,调用podofogc进行垃圾清理(GC),保存到另一个目录
"""
import subprocess
import time
from pathlib import Path
from typing import Dict, List
# ==================== 配置参数(直接修改这里) ====================
PODOFO_GC_PATH = r"D:\PDF_SOURCE\podofo_测试清理未使用对象\podofo_exe\podofogc.exe" # podofogc.exe的路径
INPUT_DIR = r"D:\3_30\pdfcore2.0\input" # 输入顶级目录
OUTPUT_DIR = r"D:\3_30\pdfcore2.0\output" # 输出顶级目录
RECURSIVE = True # 是否递归子目录
PRESERVE_STRUCTURE = True # 是否保留目录结构(True:保留, False:所有文件直接输出到根目录)
OVERWRITE = False # 是否覆盖已存在的文件(False:跳过已存在的文件)
# =================================================================
class PodofoGCProcessor:
"""Podofo GC批量处理器"""
def __init__(self):
"""初始化处理器"""
self.podofo_gc_path = Path(PODOFO_GC_PATH)
self.input_dir = Path(INPUT_DIR)
self.output_dir = Path(OUTPUT_DIR)
self.recursive = RECURSIVE
self.preserve_structure = PRESERVE_STRUCTURE
self.overwrite = OVERWRITE
# 验证podofogc是否存在
if not self.podofo_gc_path.exists():
raise FileNotFoundError(f"找不到podofogc程序: {self.podofo_gc_path}")
# 验证输入目录
if not self.input_dir.exists():
raise FileNotFoundError(f"输入目录不存在: {self.input_dir}")
# 创建输出目录
self.output_dir.mkdir(parents=True, exist_ok=True)
# 统计信息
self.stats = {
'total': 0,
'success': 0,
'failed': 0,
'skipped': 0,
'input_size_total': 0,
'output_size_total': 0
}
def get_pdf_files(self) -> List[Path]:
"""获取所有需要处理的PDF文件"""
if self.recursive:
# 递归查找所有PDF文件
pdf_files = list(self.input_dir.glob("**/*.pdf"))
else:
# 只在当前目录查找
pdf_files = list(self.input_dir.glob("*.pdf"))
# 按路径排序,保持一致性
pdf_files.sort()
return pdf_files
def get_output_path(self, input_path: Path) -> Path:
"""根据输入路径计算输出路径"""
if self.preserve_structure:
# 保留目录结构
relative_path = input_path.relative_to(self.input_dir)
output_path = self.output_dir / relative_path
else:
# 平坦结构,所有文件直接放在输出目录
output_path = self.output_dir / input_path.name
return output_path
def process_single_file(self, input_path: Path) -> Dict:
"""处理单个PDF文件"""
result = {
'input': input_path,
'output': None,
'success': False,
'error': None,
'input_size': 0,
'output_size': 0
}
try:
# 获取输出路径
output_path = self.get_output_path(input_path)
result['output'] = output_path
# 创建输出目录
output_path.parent.mkdir(parents=True, exist_ok=True)
# 检查输出文件是否已存在
if output_path.exists() and not self.overwrite:
result['error'] = "输出文件已存在,跳过"
return result
# 获取输入文件大小
input_size = input_path.stat().st_size
result['input_size'] = input_size
print(f"处理: {input_path.name}")
print(f" 源文件: {input_path}")
print(f" 目标文件: {output_path}")
# 构建命令: podofogc.exe input.pdf output.pdf
cmd = [
str(self.podofo_gc_path),
str(input_path),
str(output_path)
]
# 执行命令
start_time = time.time()
process = subprocess.run(
cmd,
capture_output=True,
text=True,
encoding='utf-8',
errors='ignore',
timeout=300 # 5分钟超时
)
elapsed_time = time.time() - start_time
if process.returncode == 0:
# 成功
output_size = output_path.stat().st_size if output_path.exists() else 0
result['output_size'] = output_size
result['success'] = True
# 计算压缩率
if input_size > 0:
compression_ratio = (1 - output_size/input_size) * 100
else:
compression_ratio = 0
print(f" ✓ 成功! 耗时: {elapsed_time:.1f}s")
print(f" 大小: {input_size/1024:.1f}KB -> {output_size/1024:.1f}KB (压缩率: {compression_ratio:.1f}%)")
else:
# 失败
error_msg = process.stderr if process.stderr else process.stdout
result['error'] = error_msg or f"返回码: {process.returncode}"
print(f" ✗ 失败: {result['error'][:100]}")
except subprocess.TimeoutExpired:
result['error'] = "处理超时(超过5分钟)"
print(f" ✗ 超时: {input_path.name}")
except Exception as e:
result['error'] = str(e)
print(f" ✗ 异常: {e}")
return result
def process_all(self) -> Dict:
"""批量处理所有PDF文件"""
# 获取所有PDF文件
print(f"\n{'='*60}")
print(f"扫描目录: {self.input_dir}")
pdf_files = self.get_pdf_files()
if not pdf_files:
print(f"未找到任何PDF文件!")
return self.stats
self.stats['total'] = len(pdf_files)
print(f"找到 {len(pdf_files)} 个PDF文件")
print(f"输出目录: {self.output_dir}")
print(f"保留目录结构: {self.preserve_structure}")
print(f"覆盖已存在文件: {self.overwrite}")
print(f"{'='*60}\n")
# 开始处理
start_time = time.time()
for i, pdf_file in enumerate(pdf_files, 1):
print(f"\n[{i}/{len(pdf_files)}] 处理中...")
result = self.process_single_file(pdf_file)
if result['success']:
self.stats['success'] += 1
self.stats['input_size_total'] += result['input_size']
self.stats['output_size_total'] += result['output_size']
elif result['error'] and "跳过" in result['error']:
self.stats['skipped'] += 1
print(f" ⊙ 跳过: {result['error']}")
else:
self.stats['failed'] += 1
elapsed_time = time.time() - start_time
self._print_summary(elapsed_time)
return self.stats
def _print_summary(self, elapsed_time: float):
"""打印处理总结"""
print(f"\n{'='*60}")
print("处理完成!统计信息:")
print(f" 总文件数: {self.stats['total']}")
print(f" 成功: {self.stats['success']}")
print(f" 失败: {self.stats['failed']}")
print(f" 跳过: {self.stats['skipped']}")
if self.stats['success'] > 0:
input_mb = self.stats['input_size_total'] / (1024 * 1024)
output_mb = self.stats['output_size_total'] / (1024 * 1024)
saved_mb = input_mb - output_mb
compression_ratio = (saved_mb / input_mb) * 100 if input_mb > 0 else 0
print(f" 总输入大小: {input_mb:.2f} MB")
print(f" 总输出大小: {output_mb:.2f} MB")
print(f" 节省空间: {saved_mb:.2f} MB ({compression_ratio:.1f}%)")
print(f" 总耗时: {elapsed_time:.1f} 秒")
print(f"{'='*60}")
def main():
"""主函数"""
try:
# 创建处理器并执行
processor = PodofoGCProcessor()
stats = processor.process_all()
# 根据结果返回退出码
return 0 if stats['failed'] == 0 else 1
except Exception as e:
print(f"程序执行失败: {e}")
return 1
if __name__ == "__main__":
exit(main())
使用方法
1. 直接修改配置参数
打开脚本,修改开头的配置部分:
python
# ==================== 配置参数(直接修改这里) ====================
PODOFO_GC_PATH = r"D:\PDF_SOURCE\podofo_测试清理未使用对象\podofo_exe\podofogc.exe"
INPUT_DIR = r"D:\3_30\pdfcore2.0\input"
OUTPUT_DIR = r"D:\3_30\pdfcore2.0\output"
RECURSIVE = True # True:递归子目录, False:只处理当前目录
PRESERVE_STRUCTURE = True # True:保留目录结构, False:所有文件直接输出
OVERWRITE = False # True:覆盖已存在文件, False:跳过已存在文件
# =================================================================
2. 运行脚本
bash
python pdf_gc_batch.py
极简版本(如果只想快速使用)
如果您想要更简单的代码,这是最小化版本:
python
import subprocess
from pathlib import Path
# 配置路径
PODOFO_GC = r"D:\PDF_SOURCE\podofo_测试清理未使用对象\podofo_exe\podofogc.exe"
INPUT_DIR = r"D:\3_30\pdfcore2.0\input"
OUTPUT_DIR = r"D:\3_30\pdfcore2.0\output"
# 创建输出目录
Path(OUTPUT_DIR).mkdir(parents=True, exist_ok=True)
# 遍历所有PDF
success = 0
failed = 0
for pdf_file in Path(INPUT_DIR).glob("**/*.pdf"):
# 计算输出路径(保留目录结构)
relative_path = pdf_file.relative_to(INPUT_DIR)
output_file = Path(OUTPUT_DIR) / relative_path
# 创建输出子目录
output_file.parent.mkdir(parents=True, exist_ok=True)
# 跳过已存在的文件
if output_file.exists():
print(f"跳过(已存在): {pdf_file.name}")
continue
# 执行podofogc
print(f"处理: {pdf_file.name}")
result = subprocess.run(
[PODOFO_GC, str(pdf_file), str(output_file)],
capture_output=True
)
if result.returncode == 0:
print(f" ✓ 成功 -> {output_file}")
success += 1
else:
print(f" ✗ 失败")
failed += 1
print(f"\n完成!成功: {success}, 失败: {failed}")
这个简化版本:
- ✅ 没有多线程
- ✅ 没有命令行参数
- ✅ 直接修改代码中的路径即可使用
- ✅ 保留目录结构
- ✅ 自动跳过已存在的文件
- ✅ 显示处理进度