2

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

// 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);

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

该进程无法访问该文件,因为它正被另一个进程使用。mscorlib.dll 中出现了“System.IO.IOException”类型的第一次机会异常

所以第一次重命名该文件夹有效,第二次抛出异常,我猜应用程序锁定了新文件夹,但如何解决它?我应该能够重命名一个文件夹两次,对吗?

4

3 回答 3

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");

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

解决方案

如果我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如果你不知道,你在做什么!通常,您不需要调用此方法。

于 2011-03-15T15:23:50.173 回答
1

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

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

于 2011-03-15T15:19:14.760 回答
1

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

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

于 2011-03-15T15:42:02.133 回答