10

openfiledialoge からファイルを選択し、deleteボタンをクリックすると画像ボックスに表示され、テキストボックスにその名前が表示されますThe process cannot access the file because it is being used by another process. 例外が発生しています 解決するためにこの例外をたくさん検索しましたが、閉じようとしたときにそれらのどれもうまくいきませんでしたテキストボックスにあるimagenameを持つファイル、つまり、pictureboxに表示しているファイル。メソッドを使用してIsFileLocked、これは特定のディレクトリパスのすべてのファイルを閉じて削除しますが、ピクチャボックスに表示されている唯一のファイルを削除するにはどうすればよいですか?

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

助けてくれてありがとう

4

5 に答える 5

6

この質問に対する(以前に)受け入れられた答えは、非常に貧弱な方法です。のドキュメント、特にファイルからビットマップを作成するオーバーロードを読むと、次System.Drawing.Bitmapのことがわかります。

ビットマップが破棄されるまで、ファイルはロックされたままになります。

コードでは、ビットマップを作成してローカル変数に保存しますが、完了したら破棄することはありません。これは、画像オブジェクトが範囲外になったが、削除しようとしている画像ファイルのロックを解放していないことを意味します。IDisposable( など)を実装するすべてのオブジェクトについてBitmapは、自分で破棄する必要があります。たとえば、この質問を参照してください (または他の人を検索してください - これは非常に重要な概念です!)。

問題を適切に修正するには、作業が完了したら画像を破棄するだけです。

 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。物事を機能させるために電話をかける必要がある場合は、他の何か間違ったことをしているという非常に強いシグナルになるはずです。

また、 1 つのファイル (表示したビットマップ)のみを削除したい場合は、削除コードが間違っており、ディレクトリ内のすべてのファイルも削除されます (これは 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;
     }
 }

次に、2 番目のボタン ハンドラーで、関心のある 1 つのファイルを削除するだけです。

        private void button2_Click(object sender, EventArgs e)
        {                
           if (!IsFileLocked(imageFileinfo))
            {                 
                imageFileinfo.Delete();
            }
        }
于 2013-08-07T13:02:02.400 に答える
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;
    }
}
于 2013-08-02T05:38:33.790 に答える
0

GetThumnailImage を使用して、静的な幅と高さを指定する必要があります。代わりに Load メソッドを使用してください。例: pictureBox1.Load(画像へのパス); これを使用すると、アプリを閉じる前に画像やフォルダーを削除しても問題ありません。他のメソッドを作成する必要はありません。お役に立てれば

于 2013-12-29T10:03:26.567 に答える
0

このコードを使用してください

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();
                }
            }
于 2013-08-02T05:25:50.447 に答える