正在删除图片框中显示的文件
本文关键字:显示 文件 删除 | 更新日期: 2023-09-27 18:26:15
我正在从openfiledialoge中选择文件,并在图片框中显示它,当我单击delete
按钮时,它的名称在文本框中显示我得到异常The process cannot access the file because it is being used by another process.
我搜索了很多这个异常来解决,但当我尝试关闭文本框中的imagename文件时,我没有发现任何一个正常工作,即我在picturebox中显示的文件;使用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
上的文档,特别是从文件中创建位图的重载,你会发现:
该文件将保持锁定状态,直到位图被释放为止。
在您的代码中,您可以创建位图并将其存储在本地变量中,但完成后永远不会处理它。这意味着您的图像对象已超出范围,但尚未释放对要删除的图像文件的锁定。对于所有实现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
,如果你需要这样做来让事情正常进行,这应该是一个非常强烈的信号,表明你做错了其他事情。
此外,如果你只想删除一个文件(你显示的位图),你的删除代码是错误的,也会删除目录中的每个文件(这只是重复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();
}
}
我遇到了同样的问题:我在PictureBox中加载了一个文件,当试图删除它时,我遇到了相同的异常
只有在显示图像时才会出现这种情况
我都试过了:
picSelectedPicture.Image.Dispose();
picSelectedPicture.Image = null;
picSelectedPicture.ImageLocation = null;
仍然得到了同样的例外
然后我在CodeProject上发现了这个:[c#]删除在picturebox中打开的图像
它不使用PictureBox.Load()
,而是从文件中创建一个Image
,并将其设置为PictureBox.Image
:
...
// Create image from file and display it in the PictureBox
Image image = GetCopyImage(imagePath);
picSelectedPicture.Image = image;
...
private Image GetCopyImage(string path) {
using (Image image = Image.FromFile(path)) {
Bitmap bitmap = new Bitmap(image);
return bitmap;
}
}
删除该文件时不再出现异常
IMHO,这是最合适的解决方案。
编辑
我忘了提一下,你可以在显示后立即安全地删除文件:
...
// Create image from file and display it in the PictureBox
Image image = GetCopyImage(imagePath);
picSelectedPicture.Image = image;
System.IO.File.Delete(imagePath);
...
使用此代码
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();
}
}
您的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;
}
}
通过使用GetThumnailImage,您必须指定静态的宽度和高度。请改用Load方法。例如:pictureBox1.加载(图像路径);通过使用此功能,u在关闭应用程序之前删除图像或文件夹不会有问题。不需要创建其他方法。希望这对有帮助