os.rename()因文件名含斜杠重命名失败 替换无效问题求解
问题根因
和特殊编码无关,是两个基础代码错误导致的:
- Python字符串是不可变对象,
str.replace()不会修改原字符串,只会返回替换后的新字符串。你的代码调用了new_name_pdf_file.replace("/", "-")但没有将返回值重新赋值给变量,所以斜杠根本没有被实际替换,正斜杠被os.path.join识别为路径层级分隔符,程序会尝试访问不存在的多级子目录,最终触发FileNotFoundError,从你的报错日志里目标路径仍然保留TOC/TOC的斜杠也能印证这点。 - 从PDF元数据取出的
title字段本身不带.pdf后缀,你直接拼接路径作为目标文件名会生成无后缀的文件,不符合预期。
另外原代码还存在两个隐患:
- 打开PDF文件时没有使用上下文管理器,会造成文件句柄泄漏
- 只替换了正斜杠,没有处理其他跨平台文件名非法字符(比如反斜杠、冒号、星号、问号等),遇到其他特殊字符还是会重命名失败
修复方案
按以下逻辑调整代码即可:
- 将字符串替换的返回值重新赋值给文件名变量
- 一次性替换所有常见的文件名非法字符
- 用
with上下文管理器打开PDF,自动关闭文件流 - 给处理后的文件名补上
.pdf后缀 - 可选增加目标文件存在性判断,避免覆盖已有文件
修复后的可运行代码:
import os from PyPDF2 import PdfReader # 全平台文件名非法字符替换规则 INVALID_FILENAME_CHARS = { "/": "-", "\\": "-", ":": "-", "*": "", "?": "", '"': "", "<": "", ">": "", "|": "" } for pdf_file in os.listdir(downloads_path): if pdf_file.lower().endswith(".pdf"): current_file_path = os.path.join(downloads_path, pdf_file) # 上下文管理器自动释放文件句柄 with open(current_file_path, "rb") as f: reader = PdfReader(f) new_filename = reader.metadata.title # 替换所有非法字符,必须将替换结果赋值回变量 for old, new in INVALID_FILENAME_CHARS.items(): new_filename = new_filename.replace(old, new) # 去除首尾空白、补充pdf后缀 new_filename = new_filename.strip() + ".pdf" target_path = os.path.join(destination_path, new_filename) # 目标文件不存在时才执行重命名 if not os.path.exists(target_path): os.rename(current_file_path, target_path)
内容的提问来源于stack exchange,提问作者double_wizz
相关产品推荐
相关产品推荐

