无法将无SheetSum工作表的文件移至错误目录,触发WinError32
解决读取Excel后文件被占用无法移动的问题
问题回顾
你遇到的问题是:当Excel文件里没有SheetSum工作表时,不仅读取会报错,后续执行shutil.move()还会抛出[WinError 32] 进程无法访问文件,因为另一个进程正在使用它的错误,导致文件没法正常移动到对应目录。你的示例代码是这样的:
def read_file(data_file): # data_file = '\rr\ex.xlsx' sheets = {} try: print("Reading file: "+data_file) sheets['df_1'] = pd.read_excel(open(data_file,'rb'), 'SheetSum') except Exception as excpt: print("Exception occurred", exc_info=True) return sheets read_file(file) shutil.move( file, dirpath +'\\processed_files')
问题根源
核心原因就是打开的文件句柄没被正确关闭:你用open(data_file,'rb')打开了文件,但不管读取成功还是失败(比如找不到SheetSum触发异常),这个文件对象都没被显式关闭。操作系统会认为这个文件还被你的进程占用着,自然就不让你移动它了。尤其是当异常触发时,代码直接return sheets,连清理的机会都没有,文件句柄就一直挂着。
解决方案:用finally或with语句做资源清理
根据你提到的finally子句特性——不管try块有没有异常都会执行,正好用来做文件的清理工作。当然更推荐用Python的with上下文管理器,它会自动帮你处理文件的关闭,不用手动写finally,更简洁安全。
方案一:with语句(推荐)
with语句会在代码块结束后自动关闭文件,哪怕中间抛出异常也不例外,完美解决句柄泄漏的问题:
import pandas as pd import shutil import traceback def read_file(data_file): sheets = {} try: print(f"Reading file: {data_file}") # 用with打开文件,自动管理生命周期 with open(data_file,'rb') as file_obj: sheets['df_1'] = pd.read_excel(file_obj, 'SheetSum') except Exception as excpt: print("Exception occurred") traceback.print_exc() # 读取失败时,把文件移到错误目录 shutil.move(data_file, dirpath + '\\error_files') return sheets # 调用函数并处理文件移动 result = read_file(file) # 只有读取成功(存在df_1)时,才移到processed_files if 'df_1' in result: shutil.move(file, dirpath + '\\processed_files')
方案二:finally显式关闭文件
如果你更倾向于用finally来控制清理逻辑,可以这样写:
import pandas as pd import shutil import traceback def read_file(data_file): sheets = {} file_obj = None # 先初始化文件对象变量 try: print(f"Reading file: {data_file}") file_obj = open(data_file,'rb') sheets['df_1'] = pd.read_excel(file_obj, 'SheetSum') except Exception as excpt: print("Exception occurred") traceback.print_exc() shutil.move(data_file, dirpath + '\\error_files') finally: # 不管成功失败,都确保文件被关闭 if file_obj is not None: file_obj.close() return sheets result = read_file(file) if 'df_1' in result: shutil.move(file, dirpath + '\\processed_files')
额外提示
- 一定要区分成功和失败的文件流向:读取成功移到
processed_files,失败移到error_files,这样不会出现逻辑混乱 - 尽量用
with语句管理文件、数据库连接这类资源,这是Python的最佳实践,能避免很多资源泄漏的问题
内容的提问来源于stack exchange,提问作者mysticBliss
相关产品推荐
相关产品推荐

