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

Python上传Google Drive后删除Zip文件遇PermissionError求助

问题描述

我编写的Python代码会遍历文件和文件夹路径列表,将其上传至Google Drive。若路径为目录,会先创建.zip文件再上传。上传完成后需删除生成的.zip文件,但删除时抛出错误:PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'C:\Temp\Newfolder.zip'。传入的file_path为C:\Temp\Newfolder,我排查后确认只有当前脚本在使用该文件,且with open(...)理应在处理完成后关闭文件,现寻求可行的优化方案。

现有代码
import os
import zipfile
import time

def add_list(filePathList, filePath): 
    filePathList.append(filePath) 
    return filePathList

def deleteFiles(filePaths):
    for path in filePaths:
        os.remove(path)

for file_path in file_paths:
    if os.path.isdir(file_path) and not os.path.splitext(file_path)[1]:
        # 压缩文件夹为.zip文件
        folder_name = os.path.basename(file_path)
        zip_file_path = os.path.join('C:\\Temp', folder_name + '.zip')
        with zipfile.ZipFile(zip_file_path, 'w') as zip_file:
            for root, dirs, files in os.walk(file_path):
                for filename in files:
                    file_to_zip = os.path.join(root, filename)
                    zip_file.write(file_to_zip, os.path.relpath(file_to_zip, file_path))
            zip_file.close()

        # 更新路径为压缩文件路径
        file_path = zip_file_path

    
    # 创建请求体
    request_body = {
        'name': os.path.basename(file_path),
        'mimeType': 'application/zip' if file_path.endswith('.zip') else 'text/plain',
        'parents': [parent_id],
        'supportsAllDrives': True
    }

    # 打开文件并执行上传请求
    with open(file_path, "rb") as f:
        media_file = MediaFileUpload(file_path, mimetype='application/zip' if file_path.endswith('.zip') else 'text/plain')
        upload_file = service.files().create(body=request_body, media_body=media_file, supportsAllDrives=True).execute()

        # 打印响应
        print(upload_file)
    

    if file_path.endswith('.zip'):
        add_list(filePathList, file_path)
    
time.sleep(10)
deleteFiles(filePathList)
优化方案

1. 移除多余的文件打开操作

你代码里的with open(file_path, "rb") as f完全是冗余的——MediaFileUpload会自行打开并管理文件句柄,额外打开的文件句柄反而可能导致冲突。直接删除这个with块:

# 直接创建MediaFileUpload并执行上传
media_file = MediaFileUpload(file_path, mimetype='application/zip' if file_path.endswith('.zip') else 'text/plain')
upload_file = service.files().create(body=request_body, media_body=media_file, supportsAllDrives=True).execute()
print(upload_file)

2. 确保MediaFileUpload释放资源

Windows下有时会因为GC延迟导致文件句柄未及时释放,使用contextlib.closing强制确保资源被释放:

from contextlib import closing

# 使用closing包裹MediaFileUpload,确保上传后立即释放文件句柄
with closing(MediaFileUpload(file_path, mimetype='application/zip' if file_path.endswith('.zip') else 'text/plain')) as media_file:
    upload_file = service.files().create(body=request_body, media_body=media_file, supportsAllDrives=True).execute()
    print(upload_file)

3. 删除压缩时的冗余关闭操作

with zipfile.ZipFile(...)会自动关闭压缩文件,手动调用zip_file.close()完全多余,直接删除这行代码即可。

4. 给删除操作增加重试机制

即便修复了句柄问题,Windows下偶尔还是会出现文件占用延迟,给删除逻辑加重试更稳妥:

def deleteFiles(filePaths):
    for path in filePaths:
        retries = 3
        while retries > 0:
            try:
                os.remove(path)
                break
            except PermissionError:
                retries -= 1
                time.sleep(1)
        if retries == 0:
            print(f"无法删除文件: {path}")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 04:05:53