0

I have used this code in many projects for cleaning up temp files before closing the application, in my current project I see problems. It is not deleting all the files every time. Approx 20-50 files and sometimes 8-12 are left undeleted. If I run the same code twice, it will delete the rest of the files. The files are not in use and I have full access.

What is going on and how can I fix this issue?

OS: Windows 10, Framework: .NET 4.5

Edit / update: - The problem is solved! ..and it was my mistake.

Thanks for all the great input from everyone! Filip Cordas pointed me to the problem. The application was terminated before the Foreach loop finished.

Note: The reason for not using FileOptions.DeleteOnClose is that the temp files are created in an extension that I do not have access to and therefore cannot set any file attribute for. I guess you cannot set it for files you didn't create with a file open command, right?

Code:

foreach (string sFile in System.IO.Directory.GetFiles("..\\", "videoBuffer_*.avi"))
{
    System.IO.File.Delete(sFile);
}
Hald
  • 16
  • 2
  • 2
    Adding some logging (files successfully deleted and files where `File.Delete` throws an exception) might help. – Klaus Gütter Jul 27 '22 at 09:45
  • 1
    1. Are you sure those not deleted files are in the list returned by `GetFiles` in the first place? 2. Do you swallow I/O-Exceptions somewhere? – Fildor Jul 27 '22 at 09:45
  • 1
    Thread.Sleep may help because | https://stackoverflow.com/questions/36578772/fileinfo-delete-is-not-deleting-the-file-immediately – Rand Random Jul 27 '22 at 09:49
  • 2
    I'm always suspicious when I see relative paths - your code assumes it knows what the process' current directory is. Problem is, there's only one and any code running in your process can change it at any time. – Damien_The_Unbeliever Jul 27 '22 at 09:52
  • "cleaning up temp files before closing" no you need to delete them *after* closing. The files need a `using` to close them then you delete. And because one of them causes an exception, the rest don't get deleted. Consider using `FileOptions.DeleteOnClose` instead – Charlieface Jul 27 '22 at 09:57
  • @Charlieface I think OP meant "closing the App". – Fildor Jul 27 '22 at 10:01
  • @Fildor Still think it's most likely that there is no `using`. And `FileOptions.DeleteOnClose` is better than manually deleting – Charlieface Jul 27 '22 at 10:05
  • @Charlieface Agreed. – Fildor Jul 27 '22 at 10:05
  • Sorry for that, yes, I meant before closing the application. The files are closed. – Hald Jul 27 '22 at 10:06
  • When is this code running exactly? Could it be that the process was closed before the foreach iterated over all the items – Filip Cordas Jul 27 '22 at 13:36
  • @FilipCordas Thanks for pointing me in this direction! The process is running separately from the process closing the application and this was why it was accidentally shut down before all files were deleted. I have fixed it now. – Hald Jul 28 '22 at 10:29

2 Answers2

0

The reason that the file isn't being deleted could be because it is in use. Or, that it does not exist at the time of deleting. I'd advice putting some checks in place, so that you can be sure the files are deleted and if they cannot be deleted, you can see why not. Within your loop, you should check if the file exists before deleting it. Also, I'd place the foreach in a while loop.

while(DirectoryContainsFiles)
{
    foreach(var file in Directory)
    {
     if(FileExistsInDirectory)
     {
      try
      {
       Delete(file)
      }
      catch(SomeException e)
      {
       Console.log(e.Message);
      }
     }
    }
}

Bare in mind, if the file does not exist, then an exception will not be thrown.

Equally, a method you could explore could be using a FileSystemWatcher, more info here: https://learn.microsoft.com/en-us/dotnet/api/system.io.filesystemwatcher?redirectedfrom=MSDN&view=net-6.0

MisterHow
  • 23
  • 5
  • There is no `Console.log`. And why do you think a FSW would help here? – Fildor Jul 27 '22 at 10:17
  • Oh of course, sorry - Throw Exception or create a throwaway message debugging '_ = e.Message;' FSW for checking, logging etc. 'OnDeleted' add a counter, see if that matches up etc... – MisterHow Jul 27 '22 at 10:44
  • 1
    The check for `FileExistsInDirectory` is not necessary; the [documentation](https://learn.microsoft.com/en-us/dotnet/api/system.io.file.delete) clearly says: "If the file to be deleted does not exist, no exception is thrown." – Klaus Gütter Jul 27 '22 at 11:40
-1

You are not able to delete that file while using it into a foreach loop. If you think about what the foreach command is doing, it will make sense. It is like trying to change a hot light build while turned on. You will get burned! You need to turn off that light bulb before removing it. In the same manner, you need to be done with using these files that you are trying to delete.

Gabriel Marius Popescu
  • 2,016
  • 2
  • 20
  • 22
  • 4
    `GetFiles` returns an array of strings. By the time you're iterating over the contents of that array, whatever filesystem operations were required to fill that array have already completed. You've taken a picture of the lightbulb before you started work. The fact that it's lit in the picture has no relevance to the current state of the lightbulb. – Damien_The_Unbeliever Jul 27 '22 at 10:29