如何检查IOException是否不够磁盘空间exceptiontypes?
如何检查IOException
是否为“磁盘空间不足”exceptiontypes?
此刻,我检查消息是否匹配“磁盘空间不足”的信息,但是我知道如果操作系统语言不是英语,这将不起作用。
您需要检查HResult
并针对ERROR_DISK_FULL(0x70)和ERROR_HANDLE_DISK_FULL(0x27) 进行HResults
,通过与0x80070000
进行OR
, 可以将其转换为HResults
。
对于.Net Framework 4.5及更高版本,您可以使用Exception.HResult
属性:
static bool IsDiskFull(Exception ex) { const int HR_ERROR_HANDLE_DISK_FULL = unchecked((int)0x80070027); const int HR_ERROR_DISK_FULL = unchecked((int)0x80070070); return ex.HResult == HR_ERROR_HANDLE_DISK_FULL || ex.HResult == HR_ERROR_DISK_FULL; }
对于较早的版本,可以使用Marshal.GetHRForException
来取回HResult,但是这有重大的副作用,不build议使用 :
static bool IsDiskFull(Exception ex) { const int ERROR_HANDLE_DISK_FULL = 0x27; const int ERROR_DISK_FULL = 0x70; int win32ErrorCode = Marshal.GetHRForException(ex) & 0xFFFF; return win32ErrorCode == ERROR_HANDLE_DISK_FULL || win32ErrorCode == ERROR_DISK_FULL; }
从MSDN文档:
请注意, GetHRForException方法设置当前线程的IErrorInfo 。 这可能会导致像ThrowExceptionForHR方法的方法,如果它被设置默认使用当前线程的IErrorInfo的方法意外的结果。
另请参见如何确定System.IO.IOException的HResult?
在.NET 4.5中, HResult
属性获取器现在是Public,因此您不必再使用Marshal.GetHRForException
(以及其副作用)。
http://msdn.microsoft.com/en-us/library/system.exception.hresult(v=vs.110).aspx states“从.NET Framework 4.5开始,HResult属性的setter受到保护,而其getter在以前的.NET Framework版本中,getter和setter都是受保护的“
所以你可以使用Justin的答案,但用ex.HResult
replaceMarshal.GetHRForException(ex)
。
好吧,这有点不好意思,但我们走了。
首先要做的是从exception中获取HResult
。 因为它是一个受保护的成员,所以我们需要一点反思来获得价值。 这里有一个扩展方法可以做到这一点:
public static class ExceptionExtensions { public static int HResultPublic(this Exception exception) { var hResult = exception.GetType().GetProperties(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance).Where(z => z.Name.Equals("HResult")).First(); return (int)hResult.GetValue(exception, null); } }
现在,在你的捕获范围内,你可以得到HResult
:
catch (Exception ex) { int hResult = ex.HResultPublic(); }
从这里,你必须解释人权。 你需要这个链接 。
我们需要得到存储在值的第一个16位的ErrorCode
,所以这里有一些操作:
int errorCode = (int)(hResult & 0x0000FFFF);
现在,请参阅系统错误代码列表,在这里我们是:
ERROR_DISK_FULL 112 (0x70)
所以testing它使用:
switch (errorCode) { case 112: // Disk full }
也许有一些“更高层次”的function来获得所有这些东西,但至less是有效的。
最简单的内联解决scheme(min .NET 4.5和C#6):
try { //... } catch (IOException ex) when ((ex.HResult & 0xFFFF) == 0x27 || (ex.HResult & 0xFFFF) == 0x70) { //... }
System.IOException有一些派生的exceptiontypes,但是没有一个派生types的声音像你的exception。 您可以查看exception的HResult或Data属性,也许这将有一个更具体的错误代码详细。 根据MSDN ,这些属性都是该exceptiontypes的一部分。 只要确保你尝试捕获特定的exceptiontypes,而不仅仅是基本的exceptiontypes。