重命名目录会在第二次重命名时重命名为dir

时间:2011-03-15 15:14:43

标签: c# rename directoryinfo

我在多次重命名目录时遇到问题,似乎锁定了文件。

// e comes from a objectListView item
DirectoryInfo di = (DirectoryInfo)e.RowObject;
DirectoryInfo parent = Directory.GetParent(di.FullName);
String newPath = Path.Combine(parent.FullName, e.NewValue.ToString());

// rename to some temp name, to help change lower and uppercast names
di.MoveTo(newPath + "__renameTemp__");
di.MoveTo(newPath);

// Trying to cleanup to prevent directory locking, doesn't work...
di = null;
parent = null;
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);

非常感谢任何帮助,因为第一次重命名工作正常,但是当尝试在重命名的文件夹上执行新的重命名时,它会引发异常:

  

该进程无法访问该文件   因为它被另一个人使用   处理。第一次机会例外   输入'System.IO.IOException'   在mscorlib.dll中

所以第一次重命名该文件夹工作,第二次抛出异常,我猜测应用程序持有新文件夹的锁,但是如何解决它?我应该能够两次重命名文件夹吗?

3 个答案:

答案 0 :(得分:10)

<强>简介

为了重现您的问题,我创建了以下方法:

private static string RenameFolder(string path, string newFolderName)
{
    DirectoryInfo di = new DirectoryInfo(path);
    DirectoryInfo parent = Directory.GetParent(di.FullName);
    String newPath = Path.Combine(parent.FullName, newFolderName);

    // rename to some temp name, to help change lower and uppercast names
    di.MoveTo(newPath + "__renameTemp__");
    di.MoveTo(newPath);

    return di.FullName;
}

当我按照以下方式调用它时,它可以工作:

var path = @"C:\Temp\test";
var newPath = RenameFolder(path, "TESt");
newPath = RenameFolder(path, "Test1");

当我像下面这样称呼它时,它不起作用:

var path = @"C:\Temp\test";
var newPath = RenameFolder(path, "TESt");
newPath = RenameFolder(newPath, "Test1");

两个调用之间的唯一区别是,在第一个版本中,我传入原始名称,即小写的所有内容。在第二种情况下,我提供新名称,即除了最后一个字母之外的所有大写字母。在两次拨打RenameFolder之间,即使睡了20秒也不会改变。奇!

<强>解决方案

如果我像这样实施RenameFolder在两种情况下均有效

private static string RenameFolder(string path, string newFolderName)
{
    String newPath = Path.Combine(Path.GetDirectoryName(path), newFolderName);

    // rename to some temp name, to help change lower and uppercast names
    Directory.Move(path, newPath + "__renameTemp__");
    Directory.Move(newPath + "__renameTemp__", newPath);

    return newPath;
}

不知何故,DirectoryInfo似乎在路径上有一个区分大小写的锁。

<强>解释
我没有,也许有人对DirectoryInfo的内部方式有一点了解,可以对这种奇怪的行为有所了解。

重点
如果您不知道,正在做什么,请不要使用GC.Collect!通常,您需要调用此方法。

答案 1 :(得分:1)

我之前的回答是错误的。正如评论中所提到的,MoveTo()方法更新DirectoryInfo对象以表示新路径,但未明确记录。

Daniel Hilgarth在回答中指出,问题可能在于其他地方。您可能需要添加逻辑,以检查何时可以再次访问该目录。

答案 2 :(得分:1)

获取Process Monitor的副本,并在重命名后查看锁定该目录的确切内容:

http://technet.microsoft.com/en-us/sysinternals/bb896645