我从openfiledialoge中选择文件,并在pictureBox中显示它,并在文本框中显示它,当我点击删除按钮我正在获得异常该进程无法访问该文件,因为它被另一个进程使用.
我搜索了很多这个异常得到解决,但我没有任何工作,当我试图关闭文件中的imagename的文件,即我在图片框中显示的文件;使用IsFileLocked方法,这会关闭和删除特定目录路径的所有文件,但是如何删除在pictureBox中显示的唯一文件,我将出错
我搜索了很多这个异常得到解决,但我没有任何工作,当我试图关闭文件中的imagename的文件,即我在图片框中显示的文件;使用IsFileLocked方法,这会关闭和删除特定目录路径的所有文件,但是如何删除在pictureBox中显示的唯一文件,我将出错
public partial class RemoveAds : Form { OpenFileDialog ofd = null; string path = @"C:\Users\Monika\Documents\Visual Studio 2010\Projects\OnlineExam\OnlineExam\Image\"; // this is the path that you are checking. public RemoveAds() { InitializeComponent(); } private void button1_Click(object sender,EventArgs e) { if (System.IO.Directory.Exists(path)) { ofd = new OpenFileDialog(); ofd.InitialDirectory = path; DialogResult dr = new DialogResult(); if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK) { Image img = new Bitmap(ofd.FileName); string imgName = ofd.SafeFileName; txtImageName.Text = imgName; pictureBox1.Image = img.GetThumbnailImage(350,350,null,new IntPtr()); ofd.RestoreDirectory = true; } } else { return; } } private void button2_Click(object sender,EventArgs e) { //Image img = new Bitmap(ofd.FileName); string imgName = ofd.SafeFileName; if (Directory.Exists(path)) { var directory = new DirectoryInfo(path); foreach (FileInfo file in directory.GetFiles()) { if(!IsFileLocked(file)) file.Delete(); } } } public static Boolean IsFileLocked(FileInfo path) { FileStream stream = null; try { //Don't change FileAccess to ReadWrite,//because if a file is in readOnly,it fails. stream = path.Open ( FileMode.Open,FileAccess.Read,FileShare.None ); } catch (IOException) { //the file is unavailable because it is: //still being written to or being processed by another thread //or does not exist (has already been processed) return true; } finally { if (stream != null) stream.Close(); } //file is not locked return false; } }
提前感谢任何帮助
解决方法
(以前)接受的这个问题的答案是很差的做法.如果您在System.Drawing.Bitmap上使用
read the documentation,特别是为从文件创建位图的重载,您会发现:
The file remains locked until the Bitmap is disposed.
在您的代码中,您创建位图并将其存储在本地变量中,但在完成后您永远不会处理它.这意味着您的图像对象已超出范围,但尚未释放其对要删除的图像文件的锁定.对于实现IDisposable的所有对象(如Bitmap),您必须自己处理它们.例如参见this question(或搜索其他人 – 这是一个非常重要的概念!).
要正确解决问题,您只需要处理完成后的图像:
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK) { Image img = new Bitmap(ofd.FileName); // create the bitmap string imgName = ofd.SafeFileName; txtImageName.Text = imgName; pictureBox1.Image = img.GetThumbnailImage(350,new IntPtr()); ofd.RestoreDirectory = true; img.Dispose(); // dispose the bitmap object }
请不要在下面的答案中采取建议 – 你几乎不需要调用GC.Collect,如果你需要做它来使事情工作,它应该是一个非常强大的信号,你正在做其他错误.
此外,如果您只想删除一个文件(您显示的位图),您的删除代码是错误的,并将删除目录中的每个文件(这只是重复Adel的要点).此外,与其保留一个全局的OpenFileDialog对象只是存储文件名,我建议摆脱那个,只保存文件信息:
FileInfo imageFileinfo; //add this //OpenFileDialog ofd = null; Get rid of this private void button1_Click(object sender,EventArgs e) { if (System.IO.Directory.Exists(path)) { OpenFileDialog ofd = new OpenFileDialog(); //make ofd local ofd.InitialDirectory = path; DialogResult dr = new DialogResult(); if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK) { Image img = new Bitmap(ofd.FileName); imageFileinfo = new FileInfo(ofd.FileName); // save the file name string imgName = ofd.SafeFileName; txtImageName.Text = imgName; pictureBox1.Image = img.GetThumbnailImage(350,new IntPtr()); ofd.RestoreDirectory = true; img.Dispose(); } ofd.Dispose(); //don't forget to dispose it! } else { return; } }
然后在您的第二个按钮处理程序中,您可以删除您感兴趣的一个文件.
private void button2_Click(object sender,EventArgs e) { if (!IsFileLocked(imageFileinfo)) { imageFileinfo.Delete(); } }