简体   繁体   English

Asp.Net Mvc删除文件问题

[英]Asp.Net Mvc Delete file issue

I have an issue with Files. 我的文件有问题。

I am doing an image importer so clients put their files on an FTP server and then they can import it in the application. 我正在执行图像导入程序,因此客户端将其文件放在FTP服务器上,然后可以将其导入应用程序中。

During the import process I copy the file in the FTP Folder to another folder with File.copy 在导入过程中,我使用File.copy将FTP文件夹中的文件复制到另一个文件夹

public List<Visuel> ImportVisuel(int galerieId, string[] images)
    {

        Galerie targetGalerie = MemoryCache.GetGaleriById(galerieId);
        List<FormatImage> listeFormats = MemoryCache.FormatImageToList();
        int i = 0;

        List<Visuel> visuelAddList = new List<Visuel>();
        List<Visuel> visuelUpdateList = new List<Visuel>();
        List<Visuel> returnList = new List<Visuel>();
        foreach (string item in images)
        {
            i++;
            Progress.ImportProgress[Progress.Guid] = "Image " + i + " sur " + images.Count() + " importées";
            string extension = Path.GetExtension(item);
            string fileName = Path.GetFileName(item);
            string originalPath = HttpContext.Current.Request.PhysicalApplicationPath + "Uploads\\";
            string destinationPath = HttpContext.Current.Server.MapPath("~/Images/Catalogue") + "\\";
            Visuel importImage = MemoryCache.GetVisuelByFilName(fileName);
            bool update = true;
            if (importImage == null) { importImage = new Visuel(); update = false; }

            Size imageSize = importImage.GetJpegImageSize(originalPath + fileName);
            FormatImage format = listeFormats.Where(f => f.width == imageSize.Width && f.height == imageSize.Height).FirstOrDefault();
            string saveFileName = Guid.NewGuid() + extension;


            File.Copy(originalPath + fileName, destinationPath + saveFileName);


            if (format != null)
            {
                importImage.format = format;
                switch (format.key)
                {
                    case "Catalogue":
                        importImage.fileName = saveFileName;
                        importImage.originalFileName = fileName;
                        importImage.dossier = targetGalerie;
                        importImage.dossier_id = targetGalerie.id;
                        importImage.filePath = "Images/Catalogue/";
                        importImage.largeur = imageSize.Width;
                        importImage.hauteur = imageSize.Height;
                        importImage.isRoot = true;
                        if (update == false) { MemoryCache.Add(ref importImage); returnList.Add(importImage); }
                        if (update == true) visuelUpdateList.Add(importImage);
                        foreach (FormatImage f in listeFormats)
                        {
                            if (f.key.StartsWith("Catalogue_"))
                            {
                                string[] keys = f.key.Split('_');
                                string destinationFileName = saveFileName.Insert(saveFileName.IndexOf('.'), "-" + keys[1].ToString());
                                string destinationFileNameDeclinaison = destinationPath + destinationFileName;
                                VisuelResizer declinaison = new VisuelResizer();
                                declinaison.Save(originalPath + fileName, f.width, f.height, 1000, destinationFileNameDeclinaison);

                                Visuel visuel = MemoryCache.GetVisuelByFilName(fileName.Insert(fileName.IndexOf('.'), "-" + keys[1].ToString()));
                                update = true;
                                if (visuel == null) { visuel = new Visuel(); update = false; }

                                visuel.parent = importImage;

                                visuel.filePath = "Images/Catalogue/";
                                visuel.fileName = destinationFileName;
                                visuel.originalFileName = string.Empty;
                                visuel.format = f;
                                //visuel.dossier = targetGalerie; On s'en fout pour les déclinaisons
                                visuel.largeur = f.width;
                                visuel.hauteur = f.height;
                                if (update == false)
                                {
                                    visuelAddList.Add(visuel);
                                }
                                else
                                {
                                    visuelUpdateList.Add(visuel);
                                }
                                //importImage.declinaisons.Add(visuel);
                            }
                        }
                        break;
                }
            }

        }
        MemoryCache.Add(ref visuelAddList);

        // FONCTION à implémenter
        MemoryCache.Update(ref visuelUpdateList);
        return returnList;
    }

After some processes on the copy (the original file is no more used) the client have a pop-up asking him if he wants to delete the original files in the ftp folder. 在对副本进行某些处理(不再使用原始文件)之后,客户端将弹出一个对话框,询问他是否要删除ftp文件夹中的原始文件。

If he clicks on Ok another method is called on the same controller and this method use 如果他单击“确定”,则在同一控制器上调用另一种方法,并且该方法使用

public void DeleteImageFile(string[] files)
    {
        for (int i = 0; i < files.Length; i++)
        {
            File.Delete(HttpContext.Current.Request.PhysicalApplicationPath + files[i].Replace(@"/", @"\"));
        }
    }

This method works fine and really delete the good files when I use it in other context. 当我在其他上下文中使用此方法时,此方法效果很好,并且实际上删除了好的文件。

But here I have an error message: 但是这里有一条错误消息:

Process can't acces to file ... because it's used by another process. 进程无法访问文件...因为它已被另一个进程使用。

Someone have an idea? 有人有主意吗?

Thank you. 谢谢。

Here's the screenshot of Process Explorer 这是Process Explorer的屏幕截图

在此处输入图片说明

There are couple of thing you can do here. 您可以在这里做几件事。

1) If you can repro it, you can use Process Explorer at that moment and see which process is locking the file and if the process is ur process then making sure that you close the file handle after your work is done. 1)如果可以对其进行复制,则可以在那时使用Process Explorer,查看哪个进程正在锁定文件,如果该进程是您的进程,则请确保在完成工作后关闭文件句柄。

2) Use try/catch around the delete statement and retry after few seconds to see if the file handle was released. 2)在delete语句周围使用try/catch ,然后在几秒钟后重试以查看文件句柄是否已释放。

3) If you can do it offline you can put in some queue and do the deletion on it later on. 3)如果您可以脱机执行此操作,则可以将其放入队列,然后稍后对其进行删除。

You solve this by using c# locks. 您可以使用c#锁解决此问题。 Just embed your code inside a lock statement and your threads will be safe and wait each other to complete processing. 只需将您的代码嵌入lock语句中,您的线程将很安全,并且彼此等待以完成处理。

I found the solution: 我找到了解决方案:

in my import method, there a call to that method 在我的导入方法中,有一个对该方法的调用

public void Save(string originalFile, int maxWidth, int maxHeight, int quality, string filePath)
        {
            Bitmap image = new Bitmap(originalFile);
            Save(ref image, maxWidth, maxHeight, quality, filePath);
        }

The bitmap maintains the file opened blocking delete. 位图维护打开的文件,阻止删除。

just added 刚刚添加

image.Dispose();

in the methos and it work fine. 在方法上,它工作正常。

Thank you for your help, and thank you for process explorer. 感谢您的帮助,也感谢您的流程浏览器。 Very useful tool 非常有用的工具

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM