在这个相对简单的程序中获得"内存不足"异常

6 .net c# io image out-of-memory

这是我的Picture.cs类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Drawing;

namespace SharpLibrary_MediaManager
{
    public class Picture:BaseFile
    {
        public int Height { get; set; }
        public int Width { get; set; }
        public Image Thumbnail { get; set; }

        /// <summary>
        /// Sets file information of an image from a given image in the file path.
        /// </summary>
        /// <param name="filePath">File path of the image.</param>
        public override void  getFileInformation(string filePath)
        {
            FileInfo fileInformation = new FileInfo(filePath);
            if (fileInformation.Exists)
            {
                Name = fileInformation.Name;
                FileType = fileInformation.Extension;
                Size = fileInformation.Length;
                CreationDate = fileInformation.CreationTime;
                ModificationDate = fileInformation.LastWriteTime;
                Height = calculatePictureHeight(filePath);
                Width = calculatePictureWidth(filePath);                
            }
        }

        public override void getThumbnail(string filePath)
        {            
            Image image = Image.FromFile(filePath);
            Thumbnail = image.GetThumbnailImage(40, 40, null, new IntPtr());            
        }

        private int calculatePictureHeight(string filePath)
        {
            var image = Image.FromFile(filePath);
            return image.Height;
        }

        private int calculatePictureWidth(string filePath)
        {
            var image = Image.FromFile(filePath);
            return image.Width;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在这里,我正在使用该类从给定文件夹中的每个文件中提取信息:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace SharpLibrary_MediaManager
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        string folderPath = @"D:\Images\PictureFolder";

        private void button1_Click(object sender, EventArgs e)
        {
            DirectoryInfo folder = new DirectoryInfo(folderPath);
            List<Picture> lol = new List<Picture>();
            foreach (FileInfo x in folder.GetFiles())
            {
                Picture picture = new Picture();
                picture.getFileInformation(x.FullName);
                lol.Add(picture);
            }

            MessageBox.Show(lol[0].Name);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我得到了Out Of Memory异常,我真的不知道为什么.这是我第一次做这样的事情所以我对批处理文件处理等很陌生.

有帮助吗?:)

编辑: 我打开任务管理器以查看内存使用情况,当我按下按钮运行方法时,我注意到我的内存使用量每秒增加100mb.

编辑2: 在我的文件夹中,我有大约103张图像,每张图像大约100kb.我需要一个解决方案,无论文件夹中有多少图像都无关紧要.有人建议打开图像,做我的魔法,然后关闭它.我真的不明白他的意思是'亲密'.

有人可以推荐不同的方法吗?:)

编辑3: 仍然出现内存不足的异常,我根据建议更改了Picture.cs中的代码,但我没有想法.有帮助吗?

public override void  getFileInformation(string filePath)
        {
            FileInfo fileInformation = new FileInfo(filePath);

            using (var image = Image.FromFile(filePath))
            {
                if (fileInformation.Exists)
                {
                    Name = fileInformation.Name;
                    FileType = fileInformation.Extension;
                    Size = fileInformation.Length;
                    CreationDate = fileInformation.CreationTime;
                    ModificationDate = fileInformation.LastWriteTime;
                    Height = image.Height;
                    Width = image.Width;
                }
            }
        }
Run Code Online (Sandbox Code Playgroud)

此外,我现在应该开一个新的问题,这个问题已经增长了一点吗?

Art*_*hur 14

您没有在Image实例上调用Dispose.还要创建一次图像,然后提取数据.

也可以看看:

http://msdn.microsoft.com/en-us/library/8th8381z.aspx

编辑 如果复制了您的代码并使用我的图片库进行了测试.我的平均值 FileSize是每个文件2-3 MB.我已经执行了你的程序,它完全应该做到了.GC完全符合我的预期.

您的程序的内存总是大约11-35 MB私人工作集,提交大小稳定在43 MB.

我在1156个文件后中止了程序,总图像大小为2.9 GB.

因此,您必须有另一个原因导致内存不足异常.

这是我的程序输出和代码:

1133: Total Size = 2.842,11 MB
1134: Total Size = 2.844,88 MB
1135: Total Size = 2.847,56 MB
1136: Total Size = 2.850,21 MB
1137: Total Size = 2.853,09 MB
1138: Total Size = 2.855,86 MB
1139: Total Size = 2.858,59 MB
1140: Total Size = 2.861,26 MB
1141: Total Size = 2.863,65 MB
1142: Total Size = 2.866,15 MB
1143: Total Size = 2.868,52 MB
1144: Total Size = 2.870,93 MB
1145: Total Size = 2.873,64 MB
1146: Total Size = 2.876,15 MB
1147: Total Size = 2.878,84 MB
1148: Total Size = 2.881,92 MB
1149: Total Size = 2.885,02 MB
1150: Total Size = 2.887,78 MB
1151: Total Size = 2.890,57 MB
1152: Total Size = 2.893,55 MB
1153: Total Size = 2.896,32 MB
1154: Total Size = 2.898,92 MB
1155: Total Size = 2.901,48 MB
1156: Total Size = 2.904,02 MB
Run Code Online (Sandbox Code Playgroud)

源代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Drawing;

namespace SharpLibrary_MediaManager
{
    public abstract class BaseFile
    {
        public string Name { get; set; }
        public string FileType { get; set; }
        public long Size { get; set; }
        public DateTime CreationDate { get; set; }
        public DateTime ModificationDate { get; set; }

        public abstract void getFileInformation(string filePath);

    }


    public class Picture : BaseFile
    {
        public int Height { get; set; }
        public int Width { get; set; }
        public Image Thumbnail { get; set; }

        public override void getFileInformation(string filePath)
        {
            FileInfo fileInformation = new FileInfo(filePath);

            using (var image = Image.FromFile(filePath))
            {
                if (fileInformation.Exists)
                {
                    Name = fileInformation.Name;
                    FileType = fileInformation.Extension;
                    Size = fileInformation.Length;
                    CreationDate = fileInformation.CreationTime;
                    ModificationDate = fileInformation.LastWriteTime;
                    Height = image.Height;
                    Width = image.Width;
                    Thumbnail = image.GetThumbnailImage(40, 40, null, new IntPtr());
                }
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            string folderPath = @"C:\Users\arthur\Pictures";

            DirectoryInfo folder = new DirectoryInfo(folderPath);
            List<Picture> lol = new List<Picture>();
            double totalFileSize = 0;
            int counter = 0;
            foreach (FileInfo x in folder.GetFiles("*.jpg", SearchOption.AllDirectories))
            {
                Picture p = new Picture();
                p.getFileInformation(x.FullName);
                lol.Add(p);
                totalFileSize += p.Size;
                Console.WriteLine("{0}: Total Size = {1:n2} MB", ++counter, totalFileSize / 1048576.0);
            }

            foreach (var p in lol)
            {
                Console.WriteLine("{0}: {1}x{2} px", p.Name, p.Width, p.Height);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Shi*_*rod 6

您必须释放打开Image对象时使用的资源.

您可以调用Dispose,也可以在Using声明中创建图像

例如

public override void getThumbnail(string filePath)
{
    using (Image image = Image.FromFile(filePath))
    {
        Thumbnail = image.GetThumbnailImage(40, 40, null, new IntPtr());
    }
}
Run Code Online (Sandbox Code Playgroud)

并且由于您的类包含一个,Image您应该实现该IDisposable接口,因此您也可以在using语句中使用它.

  • 我尽可能地使用它(即当目标类是`IDisposable`时,我的程序流允许它).您不必使用`Dispose`,并确保正确执行了内存管理. (2认同)

Jac*_*b G 5

我看到了一些问题.首先,您将随后调用CalculatePictureWidth和CalculatePictureHeight两次加载每个Image.其次,你似乎永远不会对缩略图做任何事情.第三,一旦完成从Image实例收集信息,就应该在Image实例上调用Dispose.