Python快速创建和删除目录将间歇性地导致WindowsError [错误5]

for*_*tyj 9 python windows scrapy

我在使用Scrapy时遇到了这个问题FifoDiskQueue.在Windows中,FifoDiskQueue将导致目录和文件由一个文件描述符创建并被另一个文件描述符使用(如果队列中没有更多消息,则被删除).

我将随机收到如下错误消息:

2015-08-25 18:51:30 [scrapy] INFO: Error while handling downloader output
Traceback (most recent call last):
  File "C:\Python27\lib\site-packages\twisted\internet\defer.py", line 588, in _runCallbacks
    current.result = callback(current.result, *args, **kw)
  File "C:\Python27\lib\site-packages\scrapy\core\engine.py", line 154, in _handle_downloader_output
    self.crawl(response, spider)
  File "C:\Python27\lib\site-packages\scrapy\core\engine.py", line 182, in crawl
    self.schedule(request, spider)
  File "C:\Python27\lib\site-packages\scrapy\core\engine.py", line 188, in schedule
    if not self.slot.scheduler.enqueue_request(request):
  File "C:\Python27\lib\site-packages\scrapy\core\scheduler.py", line 54, in enqueue_request
    dqok = self._dqpush(request)
  File "C:\Python27\lib\site-packages\scrapy\core\scheduler.py", line 83, in _dqpush
    self.dqs.push(reqd, -request.priority)
  File "C:\Python27\lib\site-packages\queuelib\pqueue.py", line 33, in push
    self.queues[priority] = self.qfactory(priority)
  File "C:\Python27\lib\site-packages\scrapy\core\scheduler.py", line 106, in _newdq
    return self.dqclass(join(self.dqdir, 'p%s' % priority))
  File "C:\Python27\lib\site-packages\queuelib\queue.py", line 43, in __init__
    os.makedirs(path)
  File "C:\Python27\lib\os.py", line 157, in makedirs
    mkdir(name, mode)
WindowsError: [Error 5] : './sogou_job\\requests.queue\\p-50'
Run Code Online (Sandbox Code Playgroud)

在Windows中,错误5表示拒绝访问.网上的很多解释都说明了缺少管理权限的原因,比如这篇MSDN帖子.但原因与访问权限无关.当我scrapy crawl在a中运行命令时Administrator command prompt,问题仍然存在.

然后我创建了一个像这样的小测试来试试windows和linux:

#!/usr/bin/python

import os
import shutil
import time

for i in range(1000):
    somedir = "testingdir"
    try:
        os.makedirs(somedir)
        with open(os.path.join(somedir, "testing.txt"), 'w') as out:
            out.write("Oh no")
        shutil.rmtree(somedir)
    except WindowsError as e:
        print 'round', i, e
        time.sleep(0.1)
        raise
Run Code Online (Sandbox Code Playgroud)

当我运行这个时,我会得到:

round 13 [Error 5] : 'testingdir'
Traceback (most recent call last):
  File "E:\FHT360\FHT360_Mobile\Source\keywordranks\test.py", line 10, in <module>
    os.makedirs(somedir)
  File "C:\Users\yj\Anaconda\lib\os.py", line 157, in makedirs
    mkdir(name, mode)
WindowsError: [Error 5] : 'testingdir'
Run Code Online (Sandbox Code Playgroud)

round每一次都是不同的.所以,如果我raise最终删除,我会得到这样的东西:

round 5 [Error 5] : 'testingdir'
round 67 [Error 5] : 'testingdir'
round 589 [Error 5] : 'testingdir'
round 875 [Error 5] : 'testingdir'
Run Code Online (Sandbox Code Playgroud)

它只是偶然失败,只有很小的概率,仅在Windows中.我在cygwin和linux中尝试过这个测试脚本,这个错误永远不会发生在那里.我也在另一台Windows机器上尝试了相同的代码,它出现在那里.

这有什么可能的原因?

[更新]证明截图[管理员指中文管理员]: 在此输入图像描述

还要证明测试用例在管理员命令提示符下仍然失败:

在此输入图像描述

@pss说他无法重现这个问题.我试过我们的Windows 7 Server.我安装了一个新的新的python 2.7.10 64位.我必须为圆形设置一个非常大的上限,并且开始看到在19963轮之后出现的错误:

在此输入图像描述

sor*_*rin 2

简而言之:禁用任何防病毒软件或文档索引,或者至少将它们配置为不扫描您的工作目录。

Long:您可能需要花费数月的时间来尝试解决此类问题,到目前为止,不涉及禁用防病毒软件的唯一解决方法是假设您将无法删除所有文件或目录。

在您的代码中假设这一点,并在服务启动时尝试使用不同的根子目录并尝试清理较旧的子目录,忽略删除失败。