Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 是否存在Image.FromFile为无效图像格式抛出OutOfMemoryException的原因?_C#_Exception_Exception Handling_Naming - Fatal编程技术网

C# 是否存在Image.FromFile为无效图像格式抛出OutOfMemoryException的原因?

C# 是否存在Image.FromFile为无效图像格式抛出OutOfMemoryException的原因?,c#,exception,exception-handling,naming,C#,Exception,Exception Handling,Naming,我正在编写代码,捕获此OutOfMemoryException,并抛出一个新的、更直观的异常: /// ... /// <exception cref="FormatException">The file does not have a valid image format.</exception> public static Image OpenImage( string filename ) { try { return Image.F

我正在编写代码,捕获此
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 );
    }
}
//。。。
///该文件没有有效的图像格式。
公共静态图像OpenImage(字符串文件名)
{
尝试
{
返回Image.FromFile(文件名);
}
捕获(OutOfMemoryException ex)
{
抛出new FormatException(“文件没有有效的图像格式。”,ex);
}
}

这段代码是用户可以接受的,还是出于特定原因故意抛出的
OutOfMemoryException

好吧,这是一个很好的例子,说明异常并不总是意味着它所说的。(
OutOfMemoryException
用于无效文件)可以追溯到.Net 1.0,该库的程序员可以从中选择一组更有限的异常类型。我想从那时起,它就没有被改变过,以保持向后兼容性(又称“把好钱扔进坏钱里”)


公平地说,我认为这是他们在这里可能做出的最糟糕的异常类型选择。当你打开一个文件时,它恰好很大,并且你得到一个
OutOfMemoryException
,逻辑上可以假设你实际上内存不足,并且在一段时间内出现错误的树(关于堆栈溢出有不止一个问题)。

如果是因为文件无效,它可能只是试图根据它认为是头中的一些字节来猜测它需要多大的缓冲区。通过测试清楚地记录您的意图,您应该会没事。

这是一个误导性的例外。微软:

当您尝试在.NET Framework 1.0中使用Bitmap.FromFile方法时,会收到“System.OutOfMemoryException”错误消息

如果使用位图.FromFile方法且下列条件之一为真,则可能会出现此问题:

  • 图像文件已损坏
  • 图像文件不完整
注意如果应用程序试图对未完成文件写入的文件流使用Bitmap.FromFile方法,则可能会遇到此问题。 *图像文件没有有效的图像格式,或者GDI+不支持文件的像素格式。 *程序没有访问图像文件的权限。 *BackgroundImage属性直接从Bitmap.FromFile方法设置

(位图从图像下降)


当然,当您尝试加载过大的图像时,也可能出现此异常。所以你需要考虑。

< P>不,这是历史。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)
};

当它首次登陆谷歌时,几乎不值得添加链接@音乐起源:有人可能会说根本不值得回答这个问题(那我为什么这么做?我不知道)几乎所有这些都比
OutOfMemory
更好,甚至比
GenericError
更好。尤其是
UnknownImageFormat
似乎适合于无法理解的格式。