【问题标题】:Cannot delete file from server folder无法从服务器文件夹中删除文件
【发布时间】:2023-11-21 07:22:01
【问题描述】:

我正在做一个简单的投资组合项目。我想在登录用户可以编辑的网页上显示图像。我的问题在[HttpPost] 编辑中,更具体地说是这部分:

if (ModelState.IsValid)
    {
      //updating current info 
      inDb = ModelFactory<ArtSCEn>.GetModel(db, artSCEn.ArtSCEnID);
      inDb.LastModified = DateTime.Now;
      inDb.TechUsed = artSCEn.TechUsed;
      inDb.DateOfCreation = artSCEn.DateOfCreation;
      inDb.Description = artSCEn.Description;
      inDb.ArtSC.LastModified = DateTime.Now;

      //validating img
      if (Validator.ValidateImage(img))
      {
           inDb.ImageString = Image.JsonSerialzeImage(img);
      }
      else
      {
          //return to the UI becuase we NEED a valid pic
           return View(artSCEn);
      }

      db.Entry(inDb).State = System.Data.Entity.EntityState.Modified;
      db.SaveChanges();

      //[PROBLEMATIC PART STARTS HERE]

      //updating the pic on the server
      //getting the string info
      string userArtImgFolder = Server.MapPath($"~/Content/Images/Artistic/{inDb.ArtSC.PersonID}");
      string imgNameOnServer = Path.Combine(
                    userArtImgFolder,
      $"{inDb.ArtSC.PersonID}_{inDb.ArtSC.ArtSCID}_{inDb.ArtSCEnID}{Path.GetExtension(img.FileName)}");


       //deleting previous pic 
       System.IO.File.Delete(imgNameOnServer);

       //creating a new pic
       Image.ResizePropotionatelyAndSave(img, Path.Combine(
                    userArtImgFolder,
                    $"{inDb.ArtSC.PersonID}_{inDb.ArtSC.ArtSCID}_{inDb.ArtSCEnID}{Path.GetExtension(img.FileName)}"));

 return RedirectToAction("Edit", "Art", new { id = inDb.ArtSCID });
            }

当我取回新图片并想删除以前的图片时,System.IO.File.Delete() 总是会触发它无法访问资源的异常,因为其他人正在持有它。知道那可能是什么吗? 也许这很简单,我是 ASP 新手,但就是想不通。

更新 根据 cmets 部分中的建议,我使用名为 Process Monitor 的工具检查了进程,似乎 IIS 确实锁定了资源:

顺便说一句,这个在日志中又出现了 2 次。

从操作是CreateFileMapping的事实来看,我猜它与Server.MapPath()Path.Combine()有关,但是,服务器是IDisposable(派生自Controller),所以那是我应该处理的那个吗?

另外,我要删除的资源是网站上使用的图片,这可能有问题,但在此过程中未显示网站的该部分。

【问题讨论】:

  • 我的猜测是 IIS 工作进程正在锁定您的文件。您可以通过安装解锁器等免费工具来确认锁的来源。代码中的任何内容都可能导致 IIS 工作进程保持文件的打开句柄,特别是“Image.ResizePropotionatelyAndSave”方法。我不熟悉这种方法。这是标准框架的一部分还是您使用的是不同的工具?
  • 我试试解锁器,谢谢,尽管我不认为它是Image.ResizePropotionatelyAndSave(这是我自己创造的),因为即使我评论了该函数调用,问题仍然存在。

标签: c# asp.net-mvc system.io.file


【解决方案1】:

我在@Diablo 的评论上找到了解决方案。

IIS 确实保留了资源,但Server.MapPath() 或任何代码与它无关:这是我的页面将数据返回到的编辑视图。在this SO answer 的帮助下,我发现我在使用BitMap 时粗心,在视图中没有使用 using 语句来获取一些图像统计信息。我用以下代码更新了辅助函数:

    public static float GetImageWidthFromPath(string imgAbsolutPath, int offset)
    {
        float width = 0;
        using (Bitmap b = new Bitmap(imgAbsolutPath))
        {
            width = b.Width - offset;
        }
        return width;
    }

现在 IIS 不保留资源,我可以删除文件。

【讨论】: