我正在尝试将文件夹中的bmp文件转换为jpg,然后删除旧文件。代码工作正常,但它不能删除bmp。
DirectoryInfo di = new DirectoryInfo(args[0]);
FileInfo[] files = di.GetFiles("*.bmp");
foreach (FileInfo file in files)
{
string newFile = file.FullName.Replace("bmp", "jpg");
Bitmap bm = (Bitmap)Image.FromFile(file.FullName);
bm.Save(newFile, ImageFormat.Jpeg);
}
for (int i = 0; i < files.Length; i++)
files[i].Delete();
文件未被其他程序/进程使用,如错误所示,所以我假设问题在这里。但对我来说,代码看起来很好,因为我按顺序执行所有操作。这也是程序的全部内容,因此错误不会由其他地方的代码引起。
答案 0 :(得分:5)
尝试使用using
包裹位图:
using (Bitmap bm = (Bitmap)Image.FromFile(file.FullName))
{
bm.Save(newFile, ImageFormat.Jpeg);
}
这将在保存位图对象之后对其进行处理。
答案 1 :(得分:1)
public static Image LoadImage( string fileFullName )
{
Stream fileStream = File.OpenRead( fileFullName );
Image image = Image.FromStream( fileStream );
// PropertyItems seem to get lost when fileStream is closed to quickly (?); perhaps
// this is the reason Microsoft didn't want to close it in the first place.
PropertyItem[] items = image.PropertyItems;
fileStream.Close();
foreach ( PropertyItem item in items )
{
image.SetPropertyItem( item );
}
return image;
}
答案 2 :(得分:0)
Bitmap对象封装了一个文件句柄。调用Save后,必须在位图对象上调用Dispose。
您遇到了问题,因为那些Bitmap对象尚未被垃圾回收。
答案 3 :(得分:0)
在bm.Save之后,你应该释放你的位图对象。尝试在bm.Dispose();
bm.Save(newFile, ImageFormat.Jpeg)
答案 4 :(得分:0)
来自MSDN:
在发布之前始终调用Dispose 您对图像的最后一次引用。 否则,它正在使用的资源 直到垃圾才会被释放 collector调用Image对象 最终确定方法。
我不确定在这之后您对这些图像做了什么,但有时您还需要将图像引用设置为null然后调用GC.Collect()。
答案 5 :(得分:0)
使用Image.FromFile解决问题的最佳方法是将文件句柄保持打开状态,而不是使用Image.FromStream。
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
using (Image original = Image.FromStream(fs))
{
...
使用显式的Dispose(),using()语句或将值设置为null并不能解决问题,直到垃圾收集发生(并且强制执行垃圾收集通常是一个坏主意)。