是否有一个原因Image.FromFile为无效的图像格式抛出OutOfMemoryException?

Joe*_*Joe 27 c# naming exception-handling exception

我正在编写捕获此代码的代码OutOfMemoryException并抛出一个新的,更直观的异常:

/// ...
/// <exception cref="FormatException">The file does not have a valid image format.</exception>
public static Image OpenImage( string filename )
{
    try
    {
        return Image.FromFile( filename );
    }
    catch( OutOfMemoryException ex )
    {
        throw new FormatException( "The file does not have a valid image format.", ex );
    }
}
Run Code Online (Sandbox Code Playgroud)

此代码是否为其用户所接受,或者是OutOfMemoryException出于特殊原因故意被抛出?

Han*_*ant 37

不,这是历史.在.NET出现之前,GDI +写了很长一段时间.它的SDK包装器是用C++编写的.C++中的例外情况是不确定的,并不是每个人都购买它们.谷歌没有例如.因此,要保持兼容,它会报告错误代码的问题.从来没有很好地扩展,库程序员将目标设定为故意限制可能的错误代码的数量,它减轻了客户端程序员必须报告它们的负担.

GDI +在黑桃中有这个问题,它只定义了20个错误代码.对于具有如此多外部依赖性的大量代码来说,这并不多.这本身就是一个问题,有很多方法可以搞乱图像文件.图书馆的错误报告无法完全覆盖它们.事实上,在.NET定义的标准异常派生类型之前很久就选择了这些错误代码,这当然没有帮助.

Status :: OutOfMemory错误代码被重载意味着不同的东西.有时它确实意味着内存不足,它无法分配足够的空间来存储位图位.遗憾的是,相同的错误代码报告了图像文件格式问题.这里的摩擦是它无法确定它从图像文件中读取的宽度*高度*像素是否有问题,因为位图没有足够的可用存储空间.或者,如果图像文件中的数据是垃圾.它假设图像文件不是垃圾,公平的电话,这是另一个程序的问题.所以OOM就是它的报道.

为完整起见,这些是错误代码:

enum Status
{
    Ok = 0,
    GenericError = 1,
    InvalidParameter = 2,
    OutOfMemory = 3,
    ObjectBusy = 4,
    InsufficientBuffer = 5,
    NotImplemented = 6,
    Win32Error = 7,
    WrongState = 8,
    Aborted = 9,
    FileNotFound = 10,
    ValueOverflow = 11,
    AccessDenied = 12,
    UnknownImageFormat = 13,
    FontFamilyNotFound = 14,
    FontStyleNotFound = 15,
    NotTrueTypeFont = 16,
    UnsupportedGdiplusVersion = 17,
    GdiplusNotInitialized = 18,
    PropertyNotFound = 19,
    PropertyNotSupported = 20,
#if (GDIPVER >= 0x0110)
    ProfileNotFound = 21,
#endif //(GDIPVER >= 0x0110)
};
Run Code Online (Sandbox Code Playgroud)

  • 特别是`UnknownImageFormat`似乎适合于无法理解的格式. (11认同)
  • 几乎*任何*这些都是比'OutOfMemory`更好的选择,甚至是'GenericError`. (3认同)

Mus*_*sis 7

嗯,这是一个很好的例子,说明异常并不总是意味着什么. 这个特殊情况(OutOfMemoryException对于一个无效的文件)可以追溯到.Net 1.0,它有一组更有限的异常类型,这个库的程序员可以从中选择.我认为从那以后它没有被改变以保持向后兼容性(又名"在糟糕的情况下抛出好钱").

公平地说,我认为这是他们本可以做出的异常类型最糟糕的选择.当您打开一个文件,它正好是大的,你会得到一个OutOfMemoryException,这是合乎逻辑的假设你真的是了内存和去吠叫一段时间错了(有不止一个问题StackOverflow上这个) .