如何检查 IOException 是否为 Not-Enough-Disk-Space-Exception 类型?

发布于 2025-01-05 23:57:48 字数 101 浏览 0 评论 0原文

如何检查 IOException 是否是“磁盘空间不足”异常类型?

目前,我检查该消息是否与“磁盘空间不足”之类的内容匹配,但我知道如果操作系统语言不是英语,这将不起作用。

How can I check if IOException is a "Not enough disk space" exception type?

At the moment I check to see if the message matches something like "Not enough disk space", but I know that this won't work if the OS language is not English.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

北陌 2025-01-12 23:57:48

您需要检查 HResult 并针对 ERROR_DISK_FULL (0x70)ERROR_HANDLE_DISK_FULL (0x27),其中 可以通过 OR 转换为 HResults 'ing with 0x80070000

对于 .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,但是这个 有显着的副作用,不推荐

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
当前线程(如果已设置)。

另请参阅如何确定System.IO.IOException?

You need to check the HResult and test against ERROR_DISK_FULL (0x70) and ERROR_HANDLE_DISK_FULL (0x27), which can be converted to HResults by OR'ing with 0x80070000.

For .Net Framework 4.5 and above, you can use the Exception.HResult property:

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;
}

For older versions, you can use Marshal.GetHRForException to get back the HResult, but this has significant side-effects and is not recommended:

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;
}

From the MSDN documentation:

Note that the GetHRForException method sets the IErrorInfo of the
current thread. This can cause unexpected results for methods like the
ThrowExceptionForHR methods that default to using the IErrorInfo of
the current thread if it is set.

See also How do I determine the HResult for a System.IO.IOException?

雨落□心尘 2025-01-12 23:57:48

在 .NET 4.5 中,HResult 属性 getter 现在是 Public,因此您不必再使用 Marshal.GetHRForException(及其副作用)。

http://msdn.microsoft。 com/en-us/library/system.exception.hresult(v=vs.110).aspx 指出“从 .NET Framework 4.5 开始,HResult 属性的 setter 为protected,而它的 getter 是公共的。在 .NET Framework 的早期版本中,getter 和 setter 都受保护”

因此您可以使用 Justin 的答案,但将 Marshal.GetHRForException(ex) 替换为 例如:HResult

In .NET 4.5, the HResult property getter is now Public, so you do not have to use Marshal.GetHRForException (along with its side affects) anymore.

http://msdn.microsoft.com/en-us/library/system.exception.hresult(v=vs.110).aspx states "Starting with the .NET Framework 4.5, the HResult property's setter is protected, whereas its getter is public. In previous versions of the .NET Framework, both getter and setter are protected"

So you can use Justin's answer, but replace Marshal.GetHRForException(ex) with ex.HResult.

七禾 2025-01-12 23:57:48

最简单的内联解决方案(最低 .NET 4.5 和 C# 6):

try
{
    //...
}
catch (IOException ex) when ((ex.HResult & 0xFFFF) == 0x27 || (ex.HResult & 0xFFFF) == 0x70)
{
    //...
}

Most simple inline solution (min .NET 4.5 and C# 6):

try
{
    //...
}
catch (IOException ex) when ((ex.HResult & 0xFFFF) == 0x27 || (ex.HResult & 0xFFFF) == 0x70)
{
    //...
}
绻影浮沉 2025-01-12 23:57:48

好吧,这有点老套,但我们开始吧。

首先要做的是从异常中获取 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);
    }
}

现在,在您的 catch 范围内,您可以获取 HResult

catch (Exception ex)
{
    int hResult = ex.HResultPublic();
}

从这里,您必须解释 HResult。您需要此链接

我们需要获取存储在该值的前 16 位中的 ErrorCode,因此这里有一些位操作:

int errorCode = (int)(hResult & 0x0000FFFF);

现在,请参考 系统错误代码列表,我们在这里:

ERROR_DISK_FULL
112 (0x70)

所以测试它:

switch (errorCode)
{
    case 112:
        // Disk full
}

也许有一些“更高级别”的功能可以得到所有这些东西,但至少它有效。

Well, it's a bit hacky, but here we go.

First thing to do is to get the HResult from the exception. As it's a protected member, we need a bit of reflection to get the value. Here's an extension method to will do the trick:

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

Now, in your catch scope, you can get the HResult:

catch (Exception ex)
{
    int hResult = ex.HResultPublic();
}

From here, you'll have to interpret the HResult. You'll need this link.

We need to get the ErrorCode which is stored in the 16 first bits of the value, so here's some bit operation:

int errorCode = (int)(hResult & 0x0000FFFF);

Now, refer to the list of system error codes and here we are:

ERROR_DISK_FULL
112 (0x70)

So test it using:

switch (errorCode)
{
    case 112:
        // Disk full
}

Maybe there are some "higher level" functions to get all this stuff, but at least it works.

夏花。依旧 2025-01-12 23:57:48

System.IOException 有许多派生的异常类型,但是这些派生类型听起来都不像您的异常。你可以看看异常的HResult或者Data属性,也许这会有更具体的详细错误代码。根据 MSDN 这两个属性都是该异常的一部分类型。只需确保您尝试捕获特定的异常类型,而不仅仅是基本异常类型。

System.IOException has a number of derived Exception types, however none of these derived type sound like your exception. You can look at the HResult or the Data property of the exception, perhaps this will have a more specific error code detailed. According to MSDN both those properties are part of that exception type. Just make sure you are try catching the specific exception type, not just the base Exception type.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文