How to Delete a File After Checking Whether It Exists

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



Leave a reply



Submit