我正在编写捕获此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
是否因特定原因故意被抛出?
答案 0 :(得分:37)
GDI +在黑桃中有这个问题,它只定义了20个错误代码。对于如此大量的具有如此多外部依赖性的代码而言,这并非。这本身就是一个问题,有很多方法可以搞乱图像文件。图书馆的错误报告无法完全覆盖它们。事实上,在.NET定义的标准Exception派生类型之前很久就选择了这些错误代码,这无疑有帮助。
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)
};
答案 1 :(得分:7)
嗯,这是一个很好的例子,说明异常并不总是意味着什么。 This particular case(OutOfMemoryException
表示无效文件)可以追溯到.Net 1.0,它有一组更有限的异常类型,此库的程序员可以从中选择。我认为从那以后它没有被改变以保持向后兼容性(a.k.a。“在糟糕的情况下抛出好钱”)。
公平地说,我认为这是他们本可以做出的异常类型的最糟糕选择。当你打开一个文件,它碰巧很大,而你得到一个OutOfMemoryException
时,可以合理地假设你实际上已经没有内存并且在一段时间内咆哮错误的树(这不止一个问题)在StackOverflow上关于这个)。
答案 2 :(得分:3)
如果是因为文件无效,可能只是想根据它认为的标题中的某些字节来猜测它需要多大的缓冲区。通过测试清楚地记录你的意图,你应该没事。
答案 3 :(得分:2)
这是一个误导性的例外。 Microsoft says:
当您尝试在.NET Framework 1.0中使用Bitmap.FromFile方法时收到“System.OutOfMemoryException”错误消息
使用 Bitmap.FromFile 方法时,可能会出现此问题,并且满足下列条件之一:
- 图像文件已损坏。
- 图片文件不完整。
注意如果您的应用程序尝试在未完成写入文件的文件流上使用 Bitmap.FromFile 方法,则可能会遇到此问题。 *图像文件没有有效的图像格式,或者GDI +不支持文件的像素格式。 *该程序无权访问该图像文件。 * BackgroundImage 属性直接来自 Bitmap.FromFile 方法。
(位图来自Image)
当然,当您尝试加载太大的图像时,也可能会出现此异常。所以你需要考虑这个。