File.Exists returns true after File.Delete
File.Delete
will mark file for deletion. File really will be deleted only when all handles to it are closed (if there are no such handles - it will always be deleted after File.Delete returns). As documented for DeleteFile winapi function (which is used by C# File.Delete
):
The DeleteFile function marks a file for deletion on close. Therefore,
the file deletion does not occur until the last handle to the file is
closed
Usually there are no open handles to files you delete. Or, if there are open handles - they usually don't have "delete" share (this share allows another process to mark file for deletion), so when you try to delete such file - it either gets deleted (no open handles) or access denied or similar exception is thrown (some handles, but without delete share).
However, sometimes some software, such as antivirus or search indexer, might open arbitrary files with "delete" share and hold them for some time. If you try to delete such file - it will go without errors and file really will be deleted when that software closes its handle. However, File.Exists
will return true for such "pending delete" file.
You can reproduce this issue with this simple program:
public class Program {
public static void Main() {
string path = @"G:\tmp\so\tmp.file";
// create file with delete share and don't close handle
var file = new FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.Delete);
DestroyFile(path);
GC.KeepAlive(file);
}
private static void DestroyFile(string path) {
try {
if (File.Exists(path)) {
// no error
File.Delete(path);
}
// but still exists
if (File.Exists(path)) {
throw new IOException(string.Format("Failed to delete file: '{0}'.", path));
}
}
catch (Exception ex) {
throw ex;
}
}
}
You can retry File.Exists
check forever in the program above - file will exist until you close the handle.
So that's what happens in your case - some program has open handle to this file with FileShare.Delete
.
You should expect such situation. For example - just remove that File.Exists
check, since you marked file for deletion and it will be deleted anyway.
Java better way to delete file if exists
Starting from Java 7 you can use deleteIfExists that returns a boolean (or throw an Exception) depending on whether a file was deleted or not. This method may not be atomic with respect to other file system operations. Moreover if a file is in use by JVM/other program then on some operating system it will not be able to remove it. Every file can be converted to path via toPath
method . E.g.
File file = ...;
boolean result = Files.deleteIfExists(file.toPath()); //surround it in try catch block
How can I delete a file only if it exists?
Pass the -f
argument to rm
, which will cause it to treat the situation where the named file does not exist as success, and will suppress any error message in that case:
rm -f -- filename.log
What you literally asked for would be more like:
[ -e filename.log ] && rm -- filename.log
but it's more to type and adds extra failure modes. (If something else deleted the file after [
tests for it but before rm
deletes it, then you're back at having a failure again).
As an aside, the --
s cause the filename to be treated as literal even if it starts with a leading dash; you should use these habitually if your names are coming from variables or otherwise not strictly controlled.
How to check if a file exist, delete content or create it
Try using FILE *fd = fopen("screenshot.bmp", "w");
Accorsing to tutorialspoint:
FILE *fopen(const char *filename, const char *mode)
"w"
Creates an empty file for writing. If a file with the same name already exists, its content is erased and the file is considered as a new empty file.
Update:
OP says fopen(...)
isn't allowed, but...
According to the docs you can achieve the same result as the fopen(...)
call using:
open (filename, O_WRONLY | O_CREAT | O_TRUNC, mode)
For example (from the docs):
The following example opens the file /tmp/file, either by creating it (if it does not already exist), or by truncating its length to 0 (if it does exist). In the former case, if the call creates a new file, the access permission bits in the file mode of the file are set to permit reading and writing by the owner, and to permit reading only by group members and others.
If the call to open() is successful, the file is opened for writing.
#include <fcntl.h>
...
int fd;
mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
char *filename = "/tmp/file";
...
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, mode);
...
Delete a file if it exists. If it doesn't, create it
The exception I get for a missing filename is 'OSError', not 'IOError'.
And if you get the exception, you just want to pass, and the file writing should be outside the try block.
try:
os.remove("NumPyResults.txt")
except OSError:
pass
with open("NumPyResults.txt", 'a') as results_file:
results_file.write('hi\n')
Related Topics
Execute Unit Tests Serially (Rather Than in Parallel)
In-Memory Database Doesn't Save Data
Returning a String from a C# Dll with Unmanaged Exports to Inno Setup Script
How to Use C# 6 with Web Site Project Type
How to Loop Over the Properties of a Class
Intersect with a Custom Iequalitycomparer Using Linq
Binding to Custom Control Inside Datatemplate for Itemscontrol
How to Apply a General Rule for Remapping All Property Names When Serializing with JSON.Net
How to Capitalize First Letter of First Name and Last Name in C#
How to Get the Text of a Messagebox When It Has an Icon
How to Create an Audit Trail with Entity Framework 5 and MVC 4
How to Fix the Error:"Unreachable Code Detected"
How to Get the List of All Printers in Computer
Dynamic Button Creation & Placing Them in a Predefined Order Using C#