为什么我的C#控制台应用程序会因为';内存不足'-复制文件时出现异常?
我制作了一个非常简单的程序,可以在外部硬盘上查找图片,并将其放入文件夹中。 这听起来很简单,但出于某种原因,我得到了一个“内存不足”的异常 我已经在64位Win10和32GB ram上测试了它。然而,我仍然会遇到“内存不足”的情况,这两个系统都是例外 我的平台目标是x64 以下是发生错误的代码:为什么我的C#控制台应用程序会因为';内存不足'-复制文件时出现异常?,c#,out-of-memory,C#,Out Of Memory,我制作了一个非常简单的程序,可以在外部硬盘上查找图片,并将其放入文件夹中。 这听起来很简单,但出于某种原因,我得到了一个“内存不足”的异常 我已经在64位Win10和32GB ram上测试了它。然而,我仍然会遇到“内存不足”的情况,这两个系统都是例外 我的平台目标是x64 以下是发生错误的代码: string[] filePaths = Directory.GetFiles(Stien, "*.*", SearchOption.AllDirectories);
string[] filePaths = Directory.GetFiles(Stien, "*.*", SearchOption.AllDirectories);
foreach (string file in filePaths)
{
string[] TempValue1 = file.Split(new[] { @"\" }, StringSplitOptions.None);
string FileName = TempValue1[TempValue1.Length - 1];
if (FileName.Contains(SøgeTerm)) //Checks if the name contains the search-term.
{
if (!SortDate) //If the program was told not to sort by date.
{
try
{
File.Copy(file, destination + @"\" + FileName, true);
Console.WriteLine(FileName + " => " + destination + @"\" + FileName);
}
catch (Exception e)
{
Console.WriteLine("Fejl: " + e.ToString());
}
}
else
{
Image Billede = Bitmap.FromFile(file);
string date;
try
{
PropertyItem propItem = Billede.GetPropertyItem(36867);
date = r.Replace(Encoding.UTF8.GetString(propItem.Value), "-", 2);
date = date.Split(new[] { ' ' }, StringSplitOptions.None)[0];
propItem = null;
}
catch
{
date = "UKENDT";
}
//
if (!Directory.Exists(destination + @"\" + date))
{
Directory.CreateDirectory(destination + @"\" + date);
Console.WriteLine(destination + @"\" + date);
}
File.Copy(file, destination + @"\" + date + @"\" + FileName, true); //Copies the file, and places it into the fitting folder.
Console.WriteLine(FileName + " => " + destination + @"\" + "" + date + @"\" + FileName);
date = null; //I thought this might helped clearing some memory.
Billede = null;
}
}
}
所以我的问题是:是什么导致了异常,我如何修复它?您不仅复制了文件,还将位图加载到内存中,这就是它最终耗尽内存的原因
Image Billede = Bitmap.FromFile(file);
仅将值设置为null
是不够的,您需要处理对象
因此,与其
Billede = null;
做
编辑:这样您可以在代码中进行最少的更改。然而,使用和语句是更好的做法(其他答案举例说明)
PS-有一些方法可以在不将整个图像加载到内存的情况下加载图像元数据
PPS-阅读本文,了解如何在不将整个图像加载到内存的情况下加载拍摄日期信息。它还应该使代码运行得更快:图像
和位图
实现IDisposable
。因此,您必须将它们的用法包装在using
语句中,以释放它们的资源
using (Image Billede = Bitmap.FromFile(file)){
...
}
尽管图像最终将被最终确定并发布,但在此之前您可能已经耗尽了内存。如其他答案中所述,您可以使用调用对象上的Dispose
方法
using (Image Billede = Bitmap.FromFile(file)){
...
}
但是,对于您的代码,您可能需要检查图像格式,因为image.FromFile
函数将抛出OutOfMemoryException
如果(来自MSDN):
该文件没有有效的图像格式
-或-
GDI+不支持文件的像素格式
查看异常发生在哪一行?检查异常的stacktrace以查找发生在哪一行。我打赌Bitmap.FromFile磁盘上有一些像素尺寸较大的图像文件。打开它们后是否关闭文件?损坏/无效的图像可能会引发该异常@Bitmap.FromFile(),您没有进行筛选以检查文件是否实际是图像。使用
语句可能重复的是更好的做法,因为即使引发异常或存在早期的return
语句,它也会处理。@TimRogers您不能说这是“更好的做法”,因为一切都取决于具体情况。我见过这样的情况:最好直接使用Dispose
,然后使用语句将其包装成。@m.rogalski这不是那种情况。我同意Tim,如果这很重要的话:)
using (Image Billede = Bitmap.FromFile(file)){
...
}