Python 在使用os.remove()时,大约每10000次我就有1次PermissionError

Python 在使用os.remove()时,大约每10000次我就有1次PermissionError,python,opencv,python-os,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)

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

# 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以关闭该文件。这似乎并不能解决问题。我还可以尝试什么来正确关闭该文件,或者这里是否存在其他错误

我的while framesleft:如果framesleft:是一种低效的方法,我意识到这一点。我遇到的问题是,当视频超出帧时,代码会创建1个last Corrupt.png,我无法处理。如果有人提出改进建议,我们将非常欢迎

编辑: 我已尝试捕捉原始错误:

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'

同样的问题,但现在用于创建目录。我是否应该尝试捕获每一个写入/删除操作?

此处的构造需要中间循环中断:

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()
在Python3.8之前,这些实际上是用Python编写这种循环的唯一方法

但在Python3.8及更高版本中,Python获得了一种新的赋值表达式语法,人们一直在调用walrus操作符:
:=
。使用海象操作符,您可以执行以下操作:

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

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


另外,既然创建文件只是为了在以后删除它,为什么不直接使用它,这样就不必生成唯一的文件名并祈祷没有冲突或权限问题。

请注意,
cv2.imwrite
返回一个布尔值,告诉您指令是否成功。将返回值设置为
None
不会起任何作用,尤其是不会关闭图像。似乎
imwrite
将自动关闭底层文件句柄。您是否有可能对新文件感兴趣的后台索引器或病毒扫描程序?Windows一般不支持删除“正在使用”的文件。不,没有后台索引器或病毒扫描程序。谢谢,这稍微清理了我的代码。使用临时文件比写入和删除它们有速度优势吗?@fristiprinses:我不希望有任何速度优势,但你为什么不试试看呢?我建议使用临时文件的主要原因不是速度,而是为了避免在创建临时文件时遇到一些常见的陷阱,例如竞争条件。