内存不足Image.FromFile

xsc*_*ape 18 c# image out-of-memory c#-4.0

为什么我出现内存不足错误?谢谢

if (File.Exists(photoURI))
{
    FileStream fs = new FileStream(photoURI, FileMode.Open, FileAccess.Read);
    Image img = Image.FromStream(fs);
    fs.Close();
}
Run Code Online (Sandbox Code Playgroud)

Jor*_*dão 29

Image.FromFile文档中,OutOfMemoryException如果出现以下情况,则可以抛出:

该文件没有有效的图像格式.

-要么-

GDI +不支持文件的像素格式.

检查图像格式.

此外,如果要在加载图像后立即关闭流,则必须复制图像.看看这里.GDI +必须在图像的生命周期内保持流打开.

  • 这实际上是我迄今为止发现的最愚蠢的错误。此方法可能引发此错误的所有情况都与内存完全无关。 (2认同)

Joe*_*orn 7

第一个错误:

if (File.Exists())
Run Code Online (Sandbox Code Playgroud)

文件系统是易失性的,因此对具有if条件的行和后面的行之间的文件访问可能会发生变化.不仅如此,File.Exists()可能会返回true,但如果您对文件缺少安全权限或者文件已被锁定,则FileStream仍可能抛出异常.

相反,处理此问题的正确方法是使用try/catch块.相反,将开发时间用于异常处理程序,因为无论如何都必须编写该代码.

第二个错误:

fs.Close();
Run Code Online (Sandbox Code Playgroud)

此行必须位于finally块内,或者您可能会留下打开的文件句柄.我通常建议使用一个using块来确保正确处理这种资源,但由于你已经需要try/catch,你可以使用这样的代码:

Image img = null;
FileStream fs = null;
try
{
    fs = new FileStream(photoURI, FileMode.Open, FileAccess.Read);    
    img = Image.FromStream(fs);    
}
finally
{
    fs.Close();
}
Run Code Online (Sandbox Code Playgroud)

  • 如果要在此点之后使用图像,则无法关闭流.看看[这里](http://stackoverflow.com/questions/3661799/file-delete-failing-when-image-fromfile-was-called-prior-it-despite-making-copy/3661892#3661892). (2认同)

pet*_*.fr 7

请参阅Hans Passant 的回复:

GDI+ 的编写早于 .NET 出现。它的 SDK 包装器是用 C++ 编写的。为了保持兼容性,它不能使用异常。错误情况用错误代码报告。这永远无法很好地扩展,GDI+ 只有 20 个错误代码。对于这么大的代码块来说,这并不算多。

Status::OutOfMemory 错误代码被重载以表示不同的含义。有时它确实意味着内存不足,它无法分配足够的空间来存储位图位。遗憾的是,不知道这是怎么发生的,相同的错误代码报告了图像文件格式问题。我想没有专用的错误代码可以更准确地描述它。