可以使用Directory.Move失败,因为我正在浏览该文件夹吗?

时间:2016-12-28 12:29:42

标签: c# sql-server sqlclr

我在远程FileShare中有两个文件夹,我试图将第一个文件夹移到第二个文件夹中。为此,我编写了一个CLR,几乎可以做到以下几点:

if (Directory.Exists(destinationFolder))
{
    Directory.Delete(destinationFolder, true);
}

if (Directory.Exists(sourceFolder))
{
    Directory.Move(sourceFolder, destinationFolder);
}

这可以按预期工作,但有些情况会出现以下错误:

  

System.IO.IOException:当该文件已存在时,无法创建文件。   System.IO.IOException:at System.IO .__ Error.WinIOError(Int32 errorCode,String maybeFullPath)at System.IO.Directory.InternalMove(String sourceDirName,String destDirName,Boolean checkHost)

我无法缩小范围。这对我来说似乎是随机的,因为我无法复制它。我运行这个代码块超过50次,我不能像以前那样得到相同的错误(或任何错误说实话)。   - 你看到代码有什么问题吗?   - 您对可能导致此错误的内容有任何“猜测”吗?

我唯一能想到的是,即使Directory.Delete(destinationFolder, true);返回系统也不会立即删除目录,因此当Directory.Move(sourceFolder, destinationFolder);运行时,destinationFolder仍然存在。

(2016年12月29日)这不是Cannot create a file when that file already exists when using Directory.Move的重复。在那里,用户的代码中存在“错误”并创建(Directory.CreateDirectory(destinationdirectory);)目标文件夹。我没有创建目标文件夹,但是,如果存在,我将删除它。我查看了评论和答案,但没有一个能解决我的问题。

(2016年12月30日)我已经尝试了评论和回答中的所有建议,但仍然没有什么奇怪的事情发生。没有错误也没有意外行为。

2 个答案:

答案 0 :(得分:2)

  

我唯一可以想到的是即使Directory.Delete(destinationFolder, true);返回系统没有立即删除目录,因此当Directory.Move(sourceFolder, destinationFolder);运行时,destinationFolder仍然存在。< / p>

我非常怀疑这是任何问题的原因。我想这不可能,特别是因为这是另一个系统(远程文件共享)上的文件夹而不是本地文件夹,但我仍然希望在远程系统上完成任何后写缓存对任何文件系统请求都是完全透明的,而不仅仅是其中一些。

我认为,考虑到问题中显示的代码,更有可能的是,你几乎在几乎完全相同的时间启动了两个线程并且遇到了竞争条件,其中两个线程都试图同时处理移动操作。您可以通过对代码进行以下更改来检测此类情况并避免任何错误:

string _LogFile = String.Concat(@"C:\TEMP\SQLCLR_", Guid.NewGuid(), ".log");

File.AppendAllText(_LogFile, @"Starting operation for: " + sourceFolder +
                              @" --> " + destinationFolder);

if (Directory.Exists(destinationFolder))
{
    File.AppendAllText(_LogFile, @"Deleting: " + destinationFolder);
    Directory.Delete(destinationFolder, true);
}

if (Directory.Exists(sourceFolder))
{
    if (!Directory.Exists(destinationFolder))
    {
        File.AppendAllText(_LogFile, @"Moving: " + sourceFolder);
        Directory.Move(sourceFolder, destinationFolder);
    }
    else
    {
        File.AppendAllText(_LogFile, @"Oops. " + destinationFolder +
                                     @" already exists. How odd indeed!");
    }
}

这会将操作记录到文本文件中。它将准确指出正在采取的步骤。它还会在调用&#34; move&#34;之前检查目的地是否存在,这是当前未检查的内容。

如果有两个竞争线程,您将获得2个日志文件,因为它们是使用GUID命名的。

如果,某种程度上,它实际上是远程操作系统上的延迟删除问题,那将由包含&#34;删除...&#34;的行的单个日志文件指示。然后一个用于&#34;移动...&#34;。或者,如果&#34;存在&#34;检查看到尚未删除的目的地,然后你会看到&#34; Oops&#34;。

答案 1 :(得分:0)

根据MSDN,您将在以下情况下获得该异常:

  • 尝试将目录移动到其他卷。
  • destDirName已存在。
  • sourceDirName和destDirName参数引用相同的文件或目录。
  • 其他进程正在使用其中的目录或文件。

你必须检查上述一些情况,肯定会有解决方案。

https://msdn.microsoft.com/en-us/library/system.io.directory.move(v=vs.110).aspx