IT TIP

IOException이 Not-Enough-Disk-Space-Exception 유형인지 확인하는 방법은 무엇입니까?

itqueen 2020. 11. 30. 20:32
반응형

IOException이 Not-Enough-Disk-Space-Exception 유형인지 확인하는 방법은 무엇입니까?


IOException"디스크 공간 부족"예외 유형 인지 어떻게 확인할 수 있습니까?

현재 "디스크 공간 부족"과 같은 메시지가 일치하는지 확인했지만 OS 언어가 영어가 아니면 작동하지 않을 것임을 알고 있습니다.


당신은 확인할 필요가 HResult에 대한 테스트를 ERROR_DISK_FULL (0x70)ERROR_HANDLE_DISK_FULL (0x27에) , 변환 할 수 있습니다 HResults에 의해 OR함께 보내고 '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 현재 스레드를. 이로 인해 현재 스레드 IErrorInfo 가 설정된 경우 기본적으로 사용하는 ThrowExceptionForHR 메서드와 같은 메서드에 대해 예기치 않은 결과가 발생할 수 있습니다 .

System.IO.IOException에 대한 HResult를 확인하는 방법 도 참조하십시오 .


.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는 보호되지만 getter는 보호됩니다. .NET Framework의 이전 버전에서는 getter와 setter가 모두 보호됩니다. "

그래서 당신은 저스틴의 답변을 사용하지만, 교체 할 수 있습니다 Marshal.GetHRForException(ex)ex.HResult.


글쎄, 그것은 약간 해키하지만 여기에 우리가 간다.

가장 먼저해야 할 일은 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를 해석해야합니다. 이 링크 가 필요 합니다 .

우리는 얻을 필요 ErrorCode값의 16 첫 번째 비트에 저장되어있는을, 그래서 여기에 몇 가지 비트 연산이다 :

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

이제 시스템 오류 코드 목록을 참조하십시오 .

ERROR_DISK_FULL
112 (0x70)

따라서 다음을 사용하여 테스트하십시오.

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

이 모든 것을 얻을 수있는 "상위 수준"기능이있을 수 있지만 적어도 작동합니다.


가장 간단한 인라인 솔루션 (최소 .NET 4.5 및 C # 6) :

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

System.IOException에는 여러 파생 된 Exception 유형이 있지만 이러한 파생 유형 중 어느 것도 예외처럼 들리지 않습니다. HResult 또는 예외의 Data 속성을 볼 수 있습니다. 아마도 여기에보다 구체적인 오류 코드가 자세히 나와있을 것입니다. MSDN 에 따르면 이러한 속성은 모두 해당 예외 유형의 일부입니다. 기본 예외 유형뿐만 아니라 특정 예외 유형을 포착하고 있는지 확인하십시오.

참고URL : https://stackoverflow.com/questions/9293227/how-to-check-if-ioexception-is-not-enough-disk-space-exception-type

반응형