文件夹删除时间太长(等待os.rmdir完成)

问题描述 投票:0回答:1

我有一个功能可以删除空文件夹,直到找到包含内容的文件夹。问题是,当删除子项时,循环迭代速度太快,当使用 listdir 检查父项是否为空时,子项仍然会弹出。 (虽然我还没有尝试过)我怀疑当我在删除调用后添加

sleep(0.1)
时,它会起作用。但这并不是问题的正确解决方案。需要有一种方法可以等到文件夹完全删除后再继续。
该功能(简化)可以在下面找到。当调用 

rmdir

函数时,我们循环回到顶部并到达

listdir
,上一次迭代中删除的文件夹有时仍然会弹出。
def delete_empty_folders(top_folder: str, root_folder: str) -> None:
    """Keep deleting empty folders until we reach a folder with content
    or the root folder"""

    while True:
        if not exists(top_folder):
            top_folder = dirname(top_folder)
            continue

        if samefile(top_folder, root_folder):
            break
        
        if listdir(top_folder):
            break

        rmdir(top_folder)
        top_folder = dirname(top_folder)

    return

这个

所以页面没有帮助。

python python-3.x
1个回答
0
投票

问题在于,在某些设置(操作系统、文件系统、网络挂载与否等)中,文件和文件夹会被异步删除。这意味着文件夹“提交删除”和实际删除之间存在一段时间。此时,我的算法已经再次迭代并到达

listdir

,在那里弹出所谓的已删除文件夹(因为它已被

标记
删除,但实际上尚未删除) . Python 中无法等到异步删除指令完成。我用以下(简化的)算法替代版本修复了它:

from os import listdir from os.path import exists, join, samefile from shutil import rmtree def delete_empty_folders(top_folder: str, root_folder: str) -> None: """Keep deleting empty folders until we reach a folder with content or the root folder""" parent_folder = top_folder child_folder = None while parent_folder: if exists(parent_folder): if samefile(parent_folder, root_folder): break if listdir(parent_folder) not in ([], [child_folder]): # Folder has content and it's not only the empty child break child_folder = basename(parent_folder) parent_folder = dirname(parent_folder) lowest_empty_folder = join(parent_folder, child_folder) rmtree(lowest_empty_folder, ignore_errors=True) return

此版本不会单独删除每个文件夹。它立即搜索最低的文件夹,然后递归地将它们全部删除。对于变化较少的版本,请参见下文。这里我们只是稍后检查一下该文件夹是否同时没有被删除。

from os import listdir, rmdir from os.path import exists, samefile from time import sleep def delete_empty_folders(top_folder: str, root_folder: str) -> None: """Keep deleting empty folders until we reach a folder with content or the root folder""" while True: if not exists(top_folder): top_folder = dirname(top_folder) continue if samefile(top_folder, root_folder): break if listdir(top_folder): # Check in 200ms if the folder still exists. # Could be that because of async folder deletion, # the folder is submitted for deletion but not # yet actually deleted. # Increase value for more safety. sleep(0.2) if listdir(top_folder): break rmdir(top_folder) top_folder = dirname(top_folder) return

© www.soinside.com 2019 - 2024. All rights reserved.