我在多次重命名目录时遇到问题,似乎锁定了文件。
// 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中
所以第一次重命名该文件夹工作,第二次抛出异常,我猜测应用程序持有新文件夹的锁,但是如何解决它?我应该能够两次重命名文件夹吗?
答案 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的副本,并在重命名后查看锁定该目录的确切内容: