13

After removing a file using the system.io.file class:

System.IO.File.Delete(openedPdfs.path);

I need to run some code if the file was sucessfully deleted. As long as the method does not return any value, I am checking if the file exist after the delete method. If it still exist I supposed the operation had failed.

The problem is, the deletion method works fine, but there is a couple of seconds to the file to be deleted. The Exist function return true because at the time it is checking the file is there.

How can I verify for sure if the System.IO.File.Delete(openedPdfs.path); completed successfully?

Code:

FileInfo file = new FileInfo(openedPdfs.path);    
System.IO.File.Delete(openedPdfs.path);
if (file.Exists == false)
{ ... }
else 
{ ... }
Cœur
  • 34,719
  • 24
  • 185
  • 251
Guilherme Longo
  • 2,268
  • 7
  • 40
  • 63
  • 1
    "The most elegant way I can think of is using a [FileSystemWatcher](http://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher.aspx) and subscribe to its `Deleted` event." http://stackoverflow.com/questions/9370012/waiting-for-system-to-delete-file – Tim Schmelter Jan 04 '13 at 16:12
  • 3
    Are you concerned about the case when the delete is successful, but a new file of the same name is created before your check for existence? – HABO Jan 04 '13 at 16:12
  • @TimSchmelter FileSystemWatcher has been reported to drop events under load. Some have suggested that it may be used to improve responsiveness, but that they still poll at a reduced interval to be sure to not miss events. FSW may also drag down performance, especially if the filters are unnecessarily coarse. – Andrew Dennison Oct 21 '16 at 19:30

8 Answers8

12

As others have pointed out, the File.Delete method will throw an exception in case of failure.

What they omitted to point out is that the exception will be thrown in almost all cases but not in all cases. Specifically, the File.Delete method will not throw an exception if the file to be deleted did not happen to already exist. (Duh? What were they thinking?)

So, you should check if the file exists prior to deleting it; if it does not exist, you should not do anything. If it exists, you should invoke File.Delete, and if that throws an exception, then again, you should not do anything, because the file was not deleted. Otherwise, you should do your post-successful-deletion-of-existing-file stuff.

Mike Nakis
  • 50,434
  • 8
  • 92
  • 124
  • 1
    While not an MS apologist, I think the .NET design avoids throwing exceptions when in most cases the caller doesn't care how or when the file got deleted. Exceptions are not a very performant way of reporting a not very interesting result. Directory.Create follows the same pattern. Again it resolves the race condition by not reporting the prior existence of the directory. In most use cases, it does not matter. The WinAPI handles this by explicitly reporting exactly what did or did not happen in an integer return value without throwing a costly exception. – Andrew Dennison Oct 21 '16 at 19:44
  • @AndrewDennison and I do not mean to be dissing Microsoft in every opportunity, but exceptions in .Net are so terrifically and unnecessarily costly, that they drive developers to make lame design decisions in order to avoid this cost. How do I know they are unnecessarily costly? Well, I do not have a proof for it, but the impression that I have after years of programming in each language, is that exceptions in java, although costly, are not nearly as costly as in dotNet. – Mike Nakis Oct 21 '16 at 20:37
2

Delete should throw an exception if the file wasn't deleted. Hence, your call to Exists is redundant.

Have a look at the documentation for Delete.

Daniel A. White
  • 181,601
  • 45
  • 354
  • 430
  • 3
    There is a slight delay from when File.Delete completes to when the file actually gets deleted. – tofutim Sep 19 '13 at 21:13
  • 15
    -1: Your first sentence is wrong. Delete doesn't throw when the file hadn't existed before (and hence is not deleted). Have a closer look at the documentation for Delete: "If the file to be deleted does not exist, no exception is thrown." – mkf Feb 20 '14 at 13:50
1

This is ancillary to Daniel A. White's answer: We can see the signature for the method is public static void Delete(string path). So clearly, you're not going to get feedback from the Delete call except by exception. But let's suppose you have a file that gets written or updated periodically by another process:

  1. Your program successfully delete the file.
  2. The other process recreates it immediately after the delete.
  3. Your program tests for existence with file.Exists. There's a new file with the same name, so that returns true. You're technically going down the wrong path.

This exact scenario might not be true for the problem you're currently trying to solve, but checking to see if the Delete call threw an exception is much more robust than relying on your current implementation.

Reacher Gilt
  • 1,803
  • 12
  • 25
0

It won't throw exception if file doesn't exists. In case of error it will throw exception if it couldn't be deleted, check File.Delete

Zbigniew
  • 26,284
  • 6
  • 55
  • 64
  • The documentation says "If the file to be deleted does not exist, no exception is thrown." – Moby Disk Jan 26 '15 at 20:54
  • @MobyDisk true, but I meant that it will throw exception in case of error. Technically deleting non existing file is not error. – Zbigniew Jan 27 '15 at 16:10
0

You can always use

 System.IO.File.Exists(path)

Although I agree with Daniel, if Delete does not throw exception you should be good.

Sebastian K
  • 6,055
  • 1
  • 39
  • 65
0

From the comments and suggestions you should be able to use the following to acheive your desired result

try {
  FileInfo file = new FileInfo(openedPdfs.path);    
  System.IO.File.Delete(openedPdfs.path);
  // if no exception is thrown then you should assume all has gone well and put  
  // your file successfully deleted code here.
} catch /*(Specfic exceptions can be referenced here in separate catch blocks see Daniel A. White answer)*/ {
  // If something bad happened and the file was not deleted put handling code here
} finally {
  // if some action needs to be taken regardless of whether the file was successfully deleted or not put 
  // that code here
}
Luke Baughan
  • 4,558
  • 2
  • 29
  • 52
0

I discovered that if you use the FileInfo Delete() instance method that the FileInfo instance property Exists is not updated.
For example the following code will throw a file not found exception because the file has been deleted but the second if (output_file.Exists) still evaluates to true.

FileInfo output_file;
if (output_file.Exists) output_file.Delete();   

FileStream fs;
if (output_file.Exists)
{
     fs = new FileStream(fi.FullName, FileMode.Open, FileAccess.ReadWrite);
}
else
{
     fs = new FileStream(fi.FullName, FileMode.CreateNew, FileAccess.ReadWrite);
}

I found that creating a new FileInfo from the old one fixed the problem:

FileInfo output_file;
if (output_file.Exists)
{
    output_file.Delete();
    output_file = new FileInfo(output_file.FullName);      
}

FileStream fs;
if (output_file.Exists)
{
     fs = new FileStream(fi.FullName, FileMode.Open, FileAccess.ReadWrite);
}
else
{
     fs = new FileStream(fi.FullName, FileMode.CreateNew, FileAccess.ReadWrite);
}
PiotrWolkowski
  • 7,942
  • 6
  • 43
  • 65
0
private String del(String fileLocation) {

 if (File.Exists(@fileLocation)) {
  try {
   File.Delete(@fileLocation);
  } catch (Exception e) {
   return "File couldn't be deleted because: " + e.GetType().Name;
  }
 } else {
  return "File doesn't exist";
 }

 return "File successfully deleted";
}
D.Snap
  • 1,505
  • 1
  • 19
  • 14