当我打开一个文件时,我想知道它是否被另一个进程使用,以便我可以进行特殊处理;任何其他IOException我会冒泡。 IOException的Message属性包含“进程无法访问文件'foo',因为它正在被另一个进程使用”,但这不适合程序化检测。什么是最安全,最稳健的方式来检测另一个进程正在使用的文件?如何判断被捕获的IOException是否由另一个进程使用的文件引起,而不诉诸于解析异常的Message属性
回答
时的出错代码从Win32本地函数返回的IOException
这个特殊版本被抛出是ERROR_SHARING_VIOLATION
(Documentation)。它具有0x20
数值,但实际存储为0x80070020
上异常的HRESULT
特性(它的结果的通话MakeHRFromErrorCode)。
所以检查共享冲突正在检查在IOException
的HResult
属性值0x80070020
的程序化的方式。
public static bool IsSharingViolation(this IOException ex) {
return 0x80070020 == Marshal.GetHRForException(ex);
}
但是我的确质疑你在这种情况下想要做什么,因为它是由于共享冲突而抛出的。一旦抛出异常,其他进程可能会退出,从而消除违规。
为什么不直接使用'ex.HResult'而不是'Marshal.GetHRForException'? – 2010-04-02 20:16:55
@Anders,因为HResult属性具有受保护的可访问级别,因此通常不可访问。 – JaredPar 2010-04-02 20:18:42
梦幻般的答案JaredPar,谢谢...在回答你的问题;我需要检测这种情况,因为我需要一个表达层的友好信息 - 没关系,如果由于我的应用程序的性质,冲突可能暂时不存在......再次感谢 – 2010-04-02 20:49:43
我没有足够的“代表”,所以希望这个“答案”就行了评论...
接受的答案正是我一直在寻找和完美的作品,但这里的乡亲和类似有问题质疑检查文件是否被锁定的效用。测试一个文件是否被锁定的效用函数没有多大用处是正确的,因为在接下来的语句中状态可能已经改变。
但是,尝试锁定操作然后以不同方式响应以锁定错误与一般错误的模式是有效且有用的。最明显的做法是等待一点点,然后重试操作。这可以概括为一个辅助功能是这样的:
protected static void RetryLock(Action work) {
// Retry LOCK_MAX_RETRIES times if file is locked by another process
for (int i = 1; i <= LOCK_MAX_RETRIES; i++) {
try {
work();
return;
} catch (IOException ex) {
if (i == LOCK_MAX_RETRIES || (uint) ex.HResult != 0x80070020) {
throw;
} else {
// Min should be long enough to generally allow other process to finish
// while max should be short enough such that RETRIES * MAX isn't intolerable
Misc.SleepRandom(LOCK_MIN_SLEEP_MS, LOCK_MAX_SLEEP_MS);
}
}
}
} // RetryLock
...然后可以使用这样的:
public string DoSomething() {
string strReturn = null;
string strPath = @"C:\Some\File\Path.txt";
// Do some initial work...
//----------------------------------------------------------------------------------------------------
// NESTED FUNCTION to do main logic, RetryLock will retry up to N times on lock failures
Action doWork = delegate {
using (FileStream objFile = File.Open(strPath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None)) {
// Does work here if lock succeeded, else File.Open will throw ex
strReturn = new StreamReader(objFile).ReadLine();
}
}; // delegate doWork
//----------------------------------------------------------------------------------------------------
RetryLock(doWork); // Throws original ex if non-locking related or tried max times
return strReturn;
}
...无论如何,以防万一有人有类似需求的认定发布该模式很有用。
如果你使用C#6,这是使用过滤器异常的完美情况'catch(IOException ex)when(i
- 1. 如何判断一个索引是否曾被使用过
- 2. IOException异常:该进程无法访问该文件“文件名”,因为它正被另一个进程使用
- 3. 捕获另一个函数调用的子进程的异常
- 4. IOException文件被另一个进程使用
- 5. 解决模糊语法而不诉诸于GLR解析器
- 6. 文件被另一个进程异常使用C#
- 7. 由于未捕获的异常而终止应用程序
- 8. 由于未捕获的异常'NSInvalidArgumentException'而终止应用程序
- 9. 由于未捕获异常而终止的iPhone应用程序
- 10. 由于未捕获的异常而终止应用程序NSInvalidArgumentException
- 11. AWSS3TransferManager - 由于未捕获的异常而终止应用程序
- 12. 如何判断进程挂起是否由于填充缓冲区(TCP,stdin,stdout)?
- 13. MSBuild:MSB3061 - 由于它被另一个进程使用而无法访问文件
- 14. 由于文件被另一个进程使用而打开streamreader时出错
- 15. 如何使Chrome扩展的未捕获异常处理程序(由于CORS保护而不起作用)
- 16. 连续解析由另一个进程更新的CSV文件
- 17. 如何判断一个区域是否属于某个形状?
- 18. 如何轻松判断Ninject是否可以解析一个类
- 19. IOException:另一个进程正在使用的文件
- 20. 如何判断文件是否是使用PHP的文本?
- 21. 如何判断CoInitializeSecurity是否已被调用进程?
- 22. 如何捕获JsonConverter属性中引发的异常?
- 23. 从另一个线程捕获异常
- 24. 如何判断密码是否等于另一个密码?
- 25. 如何捕获Java中另一个线程抛出的异常?
- 26. 如何判断一个Java应用程序是由Webstart的
- 27. IOException异常:进程,因为它被用来在C#中的控制台应用程序另一个进程
- 28. 使用Commons CSV进行CSV解析 - 引起IOException的引号引用
- 29. 程序如何判断另一个进程是否作为服务运行?
- 30. 由于未捕获异常'NSUnknownKeyException'而终止应用程序
该类型是否真的是IOException还是IOException派生的类型之一? – 2010-04-02 20:01:28
出于兴趣,您为什么需要以编程方式检测?一旦你发现另一个进程正在使用你的文件,你打算做什么? – 2010-04-02 20:02:13
@马克拜尔斯,看到我的评论反对接受的答案。 – 2010-04-02 20:56:29