You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WinError 32文件占用问题求助:已关闭Zip句柄仍间歇性报错

解决解压Zip文件后间歇性出现的文件占用问题

嘿,我看你碰到了个挺头疼的间歇性问题——明明已经手动调用了zf.close()关闭Zip文件句柄,还是时不时弹出WinError 32,提示文件被其他进程占用。这种情况在Windows系统上其实挺常见的,多半是文件句柄没被彻底释放,或者手动管理资源时的疏漏导致的。

问题根源分析

你代码里虽然写了zf.close(),但如果zf.extractall(dn)执行过程中突然抛出异常,zf.close()可能根本没机会执行,直接导致文件句柄泄漏。而且手动管理文件句柄本来就容易出错,Python其实提供了更可靠的方式来处理这类资源——with上下文管理器,它会自动在代码块结束时关闭资源,不管有没有异常发生。

另外,你的代码里还有几个小细节可以优化,比如手动拼接路径容易出问题,最好用os.path.join()来处理,还有没过滤非Zip文件,万一目录里有其他类型文件可能会触发错误。

修复后的完整代码

下面是我调整后的代码,既解决了句柄问题,也优化了一些细节:

import os
import re
import zipfile
import logging

logger = logging.getLogger(__name__)

def extractZipFiles(dest_directory):
    """Extracts zip files in the target directory and returns list of extracted folders"""
    extractedDirList = []
    for file in os.listdir(dest_directory):
        # 只处理后缀为.zip的文件,跳过其他类型(忽略大小写)
        if not file.lower().endswith('.zip'):
            continue
            
        file_full_path = os.path.join(dest_directory, file)
        # 生成解压目录,去掉末尾的.zip后缀
        extracted_dir = re.sub(r'\.zip$', "", file_full_path, flags=re.IGNORECASE)
        extractedDirList.append(extracted_dir)
        
        # 用with语句自动管理ZipFile,无需手动close
        with zipfile.ZipFile(file_full_path, mode='r') as zf:
            zf.extractall(extracted_dir)
            
    return extractedDirList

def removeSelectedReports(extractedDirList):
    """Removes reports starting with 'ABC_8' from extracted directories"""
    for dir_path in extractedDirList:
        # 先检查目录是否存在,避免解压失败后报错
        if not os.path.isdir(dir_path):
            logger.warning(f"Directory {dir_path} doesn't exist, skipping...")
            continue
            
        for filename in os.listdir(dir_path):
            if filename.startswith("ABC_8"):
                logger.info(f"File to be removed: {filename}")
                full_path_name = os.path.join(dir_path, filename)
                try:
                    os.remove(full_path_name)
                except OSError as e:
                    logger.error(f"Failed to delete {full_path_name}: {str(e)}")
    return extractedDirList

# 调用逻辑
extractedDirList = extractZipFiles(attributionRptDestDir)
logger.info(f"ZIP FILES EXTRACTED: {str(extractedDirList)}")
removeSelectedReports(extractedDirList)

核心修复与优化点

  • 用with语句管理ZipFile:这是解决句柄泄漏的关键!with块结束时会自动调用zf.close(),不管extractall成功还是失败,都能确保文件句柄被释放,从根源上避免资源占用问题。
  • 添加Zip文件过滤:只处理.zip后缀的文件(还加了忽略大小写的判断),避免遍历到非Zip文件时触发错误。
  • 用os.path.join()拼接路径:替代手动用+或/拼接路径,既避免了Windows和Linux的路径分隔符问题,也减少了拼写错误的可能。
  • 增加异常处理与检查:删除文件时捕获OSError,避免单个文件删除失败导致整个函数中断;遍历目录前先检查目录是否存在,处理解压失败的情况。

如果问题还没解决?试试这些排查方向

要是改完还是间歇性出现问题,可能不是代码的锅:

  • 杀毒软件/后台进程扫描:Windows Defender或者其他杀毒软件可能会实时扫描刚解压的文件或原Zip文件,导致文件被占用。可以临时关闭杀毒软件测试,或者把工作目录加入杀毒软件的排除列表。
  • 网络共享冲突:你的工作目录是网络共享目录(\\share\Workingdirectory),可能有其他用户或进程正在访问这个Zip文件。可以检查一下有没有其他人在操作这个文件,或者其他程序在后台读取它。

内容的提问来源于stack exchange,提问作者Karthik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:25:51