2009-04-19 38 views
4

我有一个奇怪的情况,在Windows Server 2008上快速连续删除和创建目录导致偶尔出现一些奇怪的错误。有时我得到IOExceptions,有一次我有一个NotAuthorizedException。奇怪的情况删除和创建目录

这是我的代码,但是当在调试器中加入时,很多异常都会被抛出。实际上,我在执行directory.delete的同时刚刚发生IOException异常,'目录不为空'!

更新 不少的答复谈论非原子目录的创建和延迟写入等是否有使这项工作的100%保证呢?理想情况下,我想要一些系统调用,即'DeleteDirectoryAndWaitForTheDirectoryToBeDeleted'和相应的系统调用,即'CreateDirectoryAndWaitForTheDirectoryToBeCreated'。

另一个更新 我把尼尔的代码的下方,试了一下我的机器上,并很快失败(经过20圈)。看来正在发生的事情是IDriveE服务可以访问该目录,并且尝试创建该目录失败并显示DELETE PENDING。我想我需要做更多的研究,比如DELETE PENDING。

就我个人而言,我不喜欢这个代码,因为它“闻起来”错了 - 但它的工作原理。

Console.WriteLine("CleanAndCreateDirectory: {0}", baseDirectory); 
while (Directory.Exists(baseDirectory)) 
{ 
    Console.WriteLine("DeleteDirectory: {0}", baseDirectory); 
    try 
    { 
     Directory.Delete(baseDirectory, true); 
    } 
    catch (Exception ex) 
    { 
     Console.Error.WriteLine(ex.Message); 
     Thread.Sleep(1000); 
    } 
} 

while (!Directory.Exists(baseDirectory)) 
{ 
    try 
    { 
     Directory.CreateDirectory(baseDirectory); 
    } 
    catch (Exception ex) 
    { 
     Console.Error.WriteLine(ex.Message); 
    } 
} 

我的怀疑是看文件系统,导致某些操作延迟,但我不知道是什么。

+1

尝试检查谁具有您要删除的目录的句柄。 Sysinterals有几个工具可能会有所帮助 - Process Explorer,FileMon,Handle等。知道哪个进程持有打开的句柄可以为您节省大量时间查找失败的原因。 – eran 2009-04-19 10:44:38

+0

说起来容易做起来难。它发生的时间是随机的,所以我可以得到一些大的日志文件。无论如何,我会继续努力 - 谢谢! – 2009-04-19 19:06:17

回答

4

当您从文件系统中删除一个项目时,它不会立即删除它 - 它会标记为在稍后的日期删除(同样如果该目录包含子文件夹/文件,它将引发异常)。

0

问题是,删除目录及其所有内容不是原子操作。因此,如果在删除代码已经“清除”目录之后,其他任何操作将文件添加到目录中,则目录的删除操作可能会失败。

您可能想要对循环进行计数,以便在删除或创建时存在实际问题时不会挂起。

2

Windows也使用一种叫做“延迟写入”的东西。所以,如果你删除了一个目录,它不会立即删除,并且它只是标记为删除。

2

以下C++代码会尽可能快地删除和重新创建目录,而在旧的Win2K盒子上没有任何问题。你可能会喜欢在你的机器上尝试它或类似的东西。

#include <iostream> 
#include <direct.h> 
using namespace std; 

int main() { 
    const char * DIRNAME = "testdir"; 
    try { 
     while(1) { 
      if (rmdir(DIRNAME) == -1) { 
       throw "could not remove directory"; 
      } 
      if (mkdir(DIRNAME) == -1) { 
       throw "could not create directory"; 
      } 
     } 
    } 
    catch(const char * s) { 
     cerr << "Error: " << s << endl; 
    } 
}