我需要移动/重命名一些加载到图片框内的图像,图像存储在应用程序可执行路径的文件夹中。在我可以移动/重命名任何图像之前,我必须确保它没有被使用,所以我尝试将应用程序的可执行路径中的另一个图像加载到此图片框中,并尝试“取消”图片框图像属性。
如果我想继续我的程序,图像仍然被锁定我使用以下代码验证了这一点:
protected virtual bool IsFileLocked(FileInfo file)
{
FileStream stream = null;
try
{
stream = file.Open(FileMode.Open, FileAccess.Read, FileShare.None);
}
catch (IOException)
{
return true;
}
finally
{
if (stream != null)
stream.Close();
}
return false;
}
我还尝试使用此处的代码:What process locks a file?
它返回了以下内容:System.Collections.Generic.List'1 [System.Diagnostics.Process]
我必须告诉你,我也在使用相同的图像和方法来对抗AccessViolationException。我不完全确定它是否是同一个问题...我保存图像的方式是错误的还是我使用它们的方式?如果您需要更多代码或信息,请与我们联系!
修改
来自TaW的链接和Anon Coward的答案都不适合我,我真的努力使其成功,我试图处理并取消图片框,图像等。我找到了一个混合的解决方案你的建议,但这是一个非常肮脏的...
var image2 = Image.FromFile(infos[i].FullName);
MemoryStream ms = new MemoryStream();
if (ImageFormat.Jpeg.Equals(image2.RawFormat))
{
// JPEG
image2.Save(ms, ImageFormat.Jpeg);
}
else if (ImageFormat.Png.Equals(image2.RawFormat))
{
// PNG
image2.Save(ms, ImageFormat.Png);
}
else if (ImageFormat.Gif.Equals(image2.RawFormat))
{
// Bitmap
image2.Save(ms, ImageFormat.Bmp);
}
else if (ImageFormat.Icon.Equals(image2.RawFormat))
{
// Icon
image2.Save(ms, ImageFormat.Icon);
}
image2.Dispose();
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
System.IO.File.Delete(infos[i].FullName);
Image newImg = Image.FromStream(ms);
newImg.Save(neuer_name2);
newImg = null;
我知道使用GarbageCollection不是正确的方法,但我不知道阻止图像的是什么......所以我仍然在这里寻找一个真正的解决方案。
答案 0 :(得分:2)
当您将该属性设置为null时,您只是将该对象标记为可用于将来某个时间点的垃圾回收,因此该对象的文件句柄将保持打开状态直到将来某个点。
如果您打算修改文件,则需要做两件事:两者都使属性为空,因此PictureBox不会尝试使用它,以及处理Image本身以便关闭文件句柄:
var image = pictureBox1.Image;
pictureBox1.Image = null;
image.Dispose();
此外,您可能遇到了issue with GDI+。您首先需要阻止Image构造函数保留对该文件的引用,您可以通过先将其读入MemoryStream,然后将其传递给构造函数来轻松完成此操作:
Image image = Image.FromStream(new MemoryStream(File.ReadAllBytes("test.png")))