python - 使用 os.remove() 时,每 10000 次左右就有 1 次出现 PermissionError

标签 python opencv python-os

我编写了一个脚本,从视频中提取帧以获取一些信息,因此我循环遍历帧,将图像写入临时文件夹,执行一些操作,删除图像:

# if frame exists, capture 
while framesleft:
    framesleft,image = vid.read()
    if framesleft:
        imfile = cv2.imwrite("temperonispaghettioni/video%03dframe%05d.png" % (videonr, framenr), image)

        # write the filename, video and frame to FrameList.csv
        row = ["bla bla bla unimportant stuff"]
        writer.writerow(row)  

        # Make sure the image is closed and remove the image     
        image = None
        imfile = None
        os.remove("temperonispaghettioni/video%03dframe%05d.png" % (videonr, framenr))

大多数时候这一切都很好。每 10000 次迭代左右一次(不是一个确切的数字并且它会变化),我会收到以下错误:

    os.remove("temperonispaghettioni/video%03dframe%05d.png" % (videonr, framenr))

PermissionError: [WinError 5] Access is denied: 'temperonispaghettioni/video000frame01218.png'

如您所见,我尝试将 image 和 imfile 设置为 None 以尝试关闭文件。这似乎并不能解决问题。我还能尝试什么来正确关闭文件,或者这里还有其他问题吗?

我也意识到,我的 whileframesleft:ifframesleft: 是一种低效的方法。我遇到的问题是,当视频超出帧时,代码会创建 1 个我无法处理的最后损坏的 .png。如果有人提出改进建议,我们将非常欢迎。

编辑: 我已经 try catch 原始错误:

try:
    os.remove("temperonispaghettioni/video%03dframe%05d.png" % (videonr, framenr))
except PermissionError:
    print('Ran into an error with deleting frame %05d of video %03d, trying again...' %(framenr,videonr))
    time.sleep(0.5)
    try:
        os.remove("temperonispaghettioni/video%03dframe%05d.png" % (videonr, framenr))
        print('Succesfully removed frame%05d of video %03d, moving on...' %(framenr,videonr))
    except PermissionError:
        print('Removal failed, frame will remain in the folder and the folder won\'t delete itself. Moving on...')

我已经将整个脚本循环运行了几百次,看看是否可以重新创建错误,到目前为止它甚至没有进入 except 阶段,但我收到了一个新错误:

 os.mkdir('temperonispaghettioni')

PermissionError: [WinError 5] Access is denied: 'temperonispaghettioni'

同样的问题,但现在要制作目录。我应该 try catch 每个写入/删除操作吗?

最佳答案

这里的构造需要中间循环中断:

while True:
    framesleft, image = vid.read()
    if not framesleft:
        break
    process(framesleft, image)

另一种方式,如果你不介意一点点重复,你也可以在循环外进行第一次读取:

framesleft, image = vid.read()
while framesleft:
    process(framesleft, image)
    framesleft, image = vid.read()

在 Python 3.8 之前,这些实际上是在 Python 中编写此类循环的唯一方法。

在 Python 3.8 及更高版本中,Python 获得了一种新的赋值表达式语法,人们将其称为海象运算符::=。使用 walrus 运算符,您可以执行如下操作:

while (frame_image := vid.read())[0]:
    framesleft, image = frame_image
    process(framesleft, image)

至于为什么你会收到权限被拒绝的错误,我真的不能说,你的帖子中没有足够的信息来真正了解这里发生了什么。您是否在启动程序之前确保该目录为空,并且不存在先前运行中可能具有不正确权限的剩余文件?您是否有另一个程序实例在后台或单独的线程/进程中运行?

此外,由于您创建文件只是为了稍后删除它,为什么不直接使用 https://docs.python.org/3.7/library/tempfile.html#tempfile.mkstemp这样您就不必生成唯一的文件名并祈祷不存在冲突或权限问题。

关于python - 使用 os.remove() 时,每 10000 次左右就有 1 次出现 PermissionError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59071780/

相关文章:

python - 从数组生成依赖组合

python - 将列表排序为字典中的值(类似于 pandas.sort_values)

opencv - JavaCV - 使用 FFmpegFrameGrabber 播放文件时出现奇怪的黑屏

c++ - Opencv HoughLines 线西塔?

python-3.x - 在buildroot镜像中添加python_opencv

python - python os模块文档中的代码示例如何创建安全漏洞?

python - 如何用pickle或其他东西加载文件夹中的每个cookie文件?

python - 为什么 Python 的标准库对发送电子邮件的支持很弱

python - 从复杂的标准 pandas 中选择非零最小值

python - os.popen().read() - charmap 解码错误