为什么我的C#-console应用程序因复制文件时“内存不足”异常而崩溃?

问题描述 投票:3回答:3

我做了一个非常简单的程序,可以在外部HDD上找到图片,并将它们放入文件夹中。这听起来很简单,但出于某种原因,我在这样做的时候得到了“Out of Memory”异常。

我已经在64位Win10上测试了4 GB的内存,64位的Win10和32 GB的内存。然而,我仍然在两个系统上都获得了“Out of Memory”异常。

我的平台目标是x64。

这是发生错误的代码:

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;
                }
            }

        }

所以我的问题:导致异常的原因是什么,我该如何解决?

c# out-of-memory
3个回答
2
投票

如其他答案中所述,您可以使用using statement以正确的方式在对象上调用Dispose方法。

using (Image Billede = Bitmap.FromFile(file)){
     ...
 }

但是,对于您的代码,您可能需要检查图像格式,因为如果(来自MSDN),Image.FromFile函数将抛出OutOfMemoryException

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

-要么-

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

看看this


6
投票

您不仅要复制文件,还要将位图加载到内存中,这就是它最终耗尽内存的原因。

Image Billede = Bitmap.FromFile(file);

仅将值设置为null是不够的,您需要处理该对象。

所以,而不是

Billede = null;

Billede.Dispose();

编辑:这样你就可以在代码中进行最少量的更改。但是,使用USING语句是一种更好的做法(其他答案举例说明)。

PS - 有一些方法可以加载图像元数据而无需将整个图像加载到内存中。

PPS - 阅读此内容以获取加载日期信息的方法,而无需将整个图像加载到内存中。它还应该使你的代码运行得更快:How can I find out when a picture was actually taken in C# running on Vista?


3
投票

ImageBitmap实施IDisposable。因此,您必须将其用法包装在using语句中以释放其资源。

 using (Image Billede = Bitmap.FromFile(file)){
     ...
 }

虽然图像最终会被最终确定并发布,但在此之前你可能会耗尽内存。

© www.soinside.com 2019 - 2024. All rights reserved.