2013-08-02 29 views
9

我從openfiledialoge中選擇文件並在文本框中顯示它在文本框中的名稱delete button我收到異常The process cannot access the file because it is being used by another process. 我搜索了很多這個異常來解決,但我沒有罰款任何他們的工作,當我試圖關閉文件與imagename這是在文本框,即文件我顯示在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; 
     } 
    } 

預先感謝任何幫助

回答

5

的(以前)接受了這個問題的答案是實踐很差。如果您read the documentationSystem.Drawing.Bitmap,特別是創建從文件中位圖超載,你會發現:

文件仍然鎖定,直到位圖設置。

在您的代碼中,您創建位圖並將其存儲在本地變量中,但是當您完成後,您永遠不會處理它。這意味着您的圖像對象已經超出了範圍,但尚未釋放對您要刪除的圖像文件的鎖定。對於實現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, 350, null, 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, 350, null, 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(); 
      } 
     } 
+0

我正在使用另一種形式保存圖像,因此在保存後還是僅在刪除和刪除時才需要處理圖像? – Durga

+0

@Durga我不明白你的意思。如果你還有其他問題,發佈另一個問題是最好的選擇 - 顯示你在那裏討論的代碼。在這種情況下(上圖),本地變量'img'正在處理 - Bitmap對象的實例,而不是它創建的文件。以後不要使用它,因爲它是一個局部變量,它超出了範圍。 –

+0

我明白你的意思,這是非常乾淨的答案,整齊地解釋,得到我如何正確地做它正確的方式非常感謝你 – Durga

-1

使用這個代碼

string imgName = ofd.SafeFileName; 
      if (Directory.Exists(path)) 
      { 

       var directory = new DirectoryInfo(path); 
       foreach (FileInfo file in directory.GetFiles()) 
       { 
        GC.Collect(); 
        GC.WaitForPendingFinalizers(); 
         file.Delete(); 
       } 
      } 
+0

我試圖用這個'IsFileLocked(FileInfo的路徑)也關閉',但它不工作,你可以建議與我可以關閉它 – Durga

+0

試一試添加這些行代碼 GC任何其他方式。蒐集(); GC.WaitForPendingFinalizers(); –

+0

之後我應該添加這在我的代碼,以便它將工作 – Durga

0

你button2_Click事件處理程序,通過所有文件循環目錄&做刪除裏面。

您需要更改類似下面的代碼:

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. 
    string fullFilePath; 

    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()); 
       fullFilePath = ofd.FilePath; 
       ofd.RestoreDirectory = true; 
      } 
     } 
     else 
     { 
      return; 
     } 
    } 

    private void button2_Click(object sender, EventArgs e) 
     { 
      FileInfo file = new FileInfo(fullFilePath); 

      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; 
    } 
} 
+0

是它正在檢查在picturebox中的文件,但它仍然沒有被刪除 – Durga

+0

在我的代碼中有一些錯誤類型,請再次檢查我的代碼。 –

0

通過使用GetThumnailImage你必須指定靜態的寬度和高度。 改爲使用Load方法。 例如:pictureBox1。負載(圖像的路徑);通過使用這個你將沒有問題在關閉應用程序之前刪除圖像或文件夾。不需要創建其他方法。 希望這有助於