我有一个目录,其中包含复杂的子目录树中的大量文件。
如果我尝试将该目录移动到同一分区上的另一个目录中,该操作理论上可能需要恒定的时间 - 基本上是重命名操作。 - 只要源目录中没有任何文件正在使用并且不存在安全问题,对吧?
如果是这样,我如何以编程方式判断是否可以将目录 A 移动到 B?
有没有任何与锁定相关的 API 可以帮助我解决这个问题?
我在 NTFS 分区上使用 C#。
I have a directory that contains lots of files in a complex tree of sub-directories.
If I try to move that directory into a another directory on the same partition, that operation could theoretically take constant time - a rename operation, basically. - as long as none of the files in the source directory are in use and there are no security issues, right?
If so, how can I tell programmatically if it's possible to move directory A to B?
Is there any locking related API that can help me with this?
I'm using C# on NTFS partitions.
发布评论
评论(2)
多任务操作系统上不存在这种“这可行吗”的 API。它们本质上是不可靠的,就像检查文件是否被锁定一样。这样的测试可能会返回“未锁定”,然后您的线程可能会被抢占,并且另一个进程中的另一个线程可能会锁定该文件。当你的线程重新获得 CPU 时,你会发现文件被锁定,尽管测试表明它没有被锁定。
执行此操作的唯一方法是实际执行该操作,然后查找错误以表明该操作不可能。 C#中的异常,使用try语句捕获IOException。处理起来并不容易,但至少 NTFS 允许您重命名或移动锁定的文件。
These kind of "could this work" APIs don't exist on a multi-tasking operating system. They are inherently unreliable, like checking if a file is locked. Such a test could return "not locked", then your thread could be pre-empted and another thread in another process could lock the file. When your thread regains the CPU, you'll find out that the file is locked, even though the test said it wasn't.
The only way to do this is to actually perform the operation, then look for an error to indicate it wasn't possible. An exception in C#, use the try statement to catch the IOException. Not that easy to deal with, but at least NTFS allows you to rename or move a file that is locked.
有很多事情会让你的移动操作失败:
并且可能还有更多您在生产中发生之前不会想到的。
无论如何,NTFS 从 Vista/2008 开始就支持事务,因此您可以将任务包装在 TransactionScope 中:
这是一篇相关文章:http://msdn.microsoft.com/en-us/magazine/cc163388.aspx
这里有一个很棒的教程:community.bartdesmet.net
There are so many things that will let your move operation fail:
And possibly many more you won't think of until it happens in production.
Anyway, NTFS supports Transactions since Vista/2008, so you could possibly wrap your task in a TransactionScope:
Here is an article about that: http://msdn.microsoft.com/en-us/magazine/cc163388.aspx
And a great tutorial here: community.bartdesmet.net