c# - Image.FromFile 为无效图像格式抛出 OutOfMemoryException 是否有原因?

标签 c# exception naming

我正在编写代码来捕获此 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 );
    }
}

此代码是否为用户所接受,或者 OutOfMemoryException 是否出于特定原因有意抛出?

最佳答案

不,这是历史。 GDI+ 是在 .NET 出现之前编写的。它的 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)
};

关于c# - Image.FromFile 为无效图像格式抛出 OutOfMemoryException 是否有原因?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23469219/

相关文章:

java - LayoutInflater 异常

java - 如果所请求的 key 不存在,应该抛出什么异常?

javascript - 以数字开头的类或方法名称,为什么不呢?

Kubernetes Pod命名约定

PHP 命名空间类命名约定

c# 在图片框上绘制一个矩形?

c# - 如何从 C# (2.0) 中的属性获取属性的名称

haskell - 如何将 IOError 异常与本地相关异常结合起来?

c# - hosting.json 有什么意义,因为 appsettings.json 就足够了

c# - 删除 OpenFileDialog C# 中的位置栏