C# 文件删除,文件正在被其他进程使用

6

在尝试删除图像文件时,我遇到了一个问题。

我总是收到一个错误消息,上面写着:IOExeption was unhandled。因为文件正在被另一个进程使用,所以访问被拒绝。

我不知道是哪个进程,并且不知道如何解决这个问题。

private void comboBox3_SelectedIndexChanged(object sender, EventArgs e)
        {            
            Album album = GetAlbum(comboBox1.SelectedIndex);
            Photo photo = GetPhoto(comboBox1.SelectedIndex, comboBox3.SelectedIndex);
txtPhotoPath.Text = Directory.GetCurrentDirectory() + "\\" + photo.SPath;
lblExtention.Text = photo.SExtention; txtPhotoTitle.Text = photo.STitle; pctrbFoto.Image = Image.FromFile(foto.SPath).GetThumbnailImage(GetWitdth(photo.SPath, GetHeight(photo.SPath, 150)), GetfHeight(photo.SPath, 150), null, new IntPtr()); } private void btnChangePhoto_Click(object sender, EventArgs e) { Album album = GetAlbum(comboBox1.SelectedIndex); Photo photo = GetPhoto(comboBox1.SelectedIndex, comboBox3.SelectedIndex);
File.Delete("Albums\\Images\\" + photo.STitle + foto.SExtention);
photo.SExtention = lblExtention.Text; photo.STitle = txtPhotoTitel.Text; Photo.SPath = txtPath.Text;
File.Copy(photo.SPath, "Albums\\Images\\" + photo.STitle + photo.SExtention);
}

谢谢, Vinzcent


感谢所有人的帮助。

我使用了这个方法,现在它运行得非常好。


你的进程正在使用文件,你需要将图像设置为空,使用类似于这样的代码:

var img = Image.FromFile(foto.SPath).GetThumbnailImage(GetWitdth(photo.SPath, GetHeight(photo.SPath, 150)), GetfHeight(photo.SPath, 150), null, new IntPtr());

pctrbFoto.Image = img;

img = null;

GC.Collect();

10个回答

6

我首先会查看您的GetPhoto方法。您是否有一个未关闭的StreamReader?确保在删除之前进行任何文件I/O时,先关闭这些连接。GetPhoto()方法是做什么的?


3

获取缩略图的位置:

using(Image img = Image.FromFile(foto.SPath))
{
  pctrbPhoto. Image = img.GetThumbnailImage(
  GetWitdth(photo.SPath, GetHeight(photo.SPath, 150)), 
  GetfHeight(photo.SPath, 150), null, new IntPtr()); 
}

应该确保在使用完源图像后将其关闭以释放资源。

如果您不这样做,从文件中加载的图像将一直存在,直到垃圾回收器决定释放它,这可能需要一些时间。

使用FromFile加载的图像会保持其来源文件处于打开状态。


3

首先,您需要确定是您的应用程序还是另一个应用程序打开了该文件。

您可以使用Mark Russinovich的Process Explorer查看哪个程序打开了特定的文件或目录。它是Windows Sysinternals一系列出色实用工具的一部分,每个程序员/IT专业人员都应该使用(或至少知道)。

您可以在此处获取它:http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx


我同意。但我没有看到显示程序正在使用的文件的选项。 - TamusJRoyce

2

如果您的进程使用文件,您需要将图像设置为null。可以使用以下代码:

using(var img = Image.FromFile(foto.SPath).GetThumbnailImage(GetWitdth(photo.SPath, GetHeight(photo.SPath, 150)), GetfHeight(photo.SPath, 150), null, new IntPtr()))
  pctrbFoto.Image = img;

6
通常情况下,调用GC.Collect是一个不好的想法:http://blogs.msdn.com/ricom/archive/2004/11/29/271829.aspx 由于Image实现了IDisposable接口,因此你应该调用img.Dispose(),或者(更好的做法)使用一个"using"块。 - Bradley Grainger

2
当您在comboBox3_SelectedIndexChanged中调用Image.FromFile时,可能还有其他地方,您没有处理Image对象。因此,您的程序会使文件处于使用状态。
每次打开图像时都需要处理它。

1

当其他方法都失败时,您可以使用MoveFileEx在下一次重启时删除文件。


0

...但是,如果您的应用程序正在运行在Web托管计划上呢?您无法在共享服务器上运行任何软件。

我尝试过使用dispose()和其他选项,但我无法像Vinzcent那样删除文件。

该死的IIS :@


0

你可以使用Unlocker程序告诉你哪个程序锁定了该文件。

注意:已删除Unlocker程序的链接 - 包含恶意软件。


你也可以使用进程资源管理器来查看哪些程序锁定了文件(http://technet.microsoft.com/zh-cn/sysinternals/bb896653.aspx)。 - Brian

0

在尝试从同一软件中删除/修改先前保存的文件时会出现此问题。我通过添加以下代码解决了这个问题:

System.GC.Collect(); 
System.GC.WaitForPendingFinalizers();


File.Delete(MyFile);

-1

我曾经使用过类似于thestarSadegh发布的代码,但在某些情况下它并没有起到作用或帮助,所以我找到了另一种解决方案。我已经在这里发布了它。

以下是代码(在查看链接和问题后,您可能会更好地理解它):

   var imageAsByteArray = File.ReadAllBytes(imagePath);

   // I use as example a pictureBox:
   pictureBox1.Image = byteArrayToImage(imageAsByteArray);

   // Or/and safe/copy/replace it:
   File.WriteAllBytes(picture_Path, imageAsByteArray);

如果你想的话,你也可以立即删除这张(新)图片!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接