C# FORM图片分类复制程序内存占用过高崩溃该如何解决
内存溢出问题原因与修复方案
核心问题
- 逻辑顺序错误:代码未先判断文件格式合法性,就调用
Image.FromFile加载所有文件,会强行加载MP4等非图片文件,产生大量无效内存占用,甚至抛出异常。 - 非托管资源未释放:
Image是GDI+封装的非托管资源,当前没有主动释放资源,循环处理大量文件时,未释放的Image会持续占用内存,最终触发内存溢出。 - 额外可优化点:扩展名判断逻辑冗余,路径拼接方式不规范,且现有逻辑无法读取MP4视频的宽高,
Image.FromFile不支持解析视频文件。
修复后代码
// 提前定义允许的扩展名集合,统一转小写判断,不用重复写大小写 var allowedExtensions = new HashSet<string> { ".png", ".jpeg", ".jpg", ".mp4" }; foreach (var srcPath in Directory.GetFiles(sourcePath)) { string name = Path.GetFileName(srcPath); string ext = Path.GetExtension(srcPath).ToLower(); // 先判断格式是否合法,不合法直接跳过后续逻辑 if (!allowedExtensions.Contains(ext)) { continue; } int width, height; // 图片格式用Image读取宽高,用using包裹自动释放资源 if (ext != ".mp4") { using (Image img = Image.FromFile(srcPath)) { width = img.Width; height = img.Height; } } else { // 此处补充MP4宽高读取逻辑,可引入MediaToolkit等库实现,现有逻辑不支持读取视频宽高 // 临时示例逻辑,你可以按需替换 continue; } // 用Path.Combine拼接路径,避免格式错误 string targetPath = height > width ? Path.Combine(pathString, name) : Path.Combine(pathString2, name); File.Copy(srcPath, targetPath, true); }
额外说明
如果需要实现MP4文件的宽高读取,可引入NuGet包MediaToolkit,对应读取逻辑如下:
using (var videoFile = new MediaToolkit.MediaFile(srcPath)) { width = videoFile.Metadata.VideoData.Width; height = videoFile.Metadata.VideoData.Height; }
内容的提问来源于stack exchange,提问作者Martin Mészáros
相关产品推荐
相关产品推荐

