Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I properly open a file for deletion?

I thought this is a completely trivial task but it gave me some headache. I would like to open a file to ensure I got exclusive access, test for certain conditions, then delete it.

Right now I'm using a 99% approach:

FileStream s = null;
try {
    s = new FileStream (
        path,
        FileMode.Open,
        FileAccess.ReadWrite,
        FileShare.None);
    // some stuff about the file is checked here
    s.Dispose ();
    // hope the file is not accessed by someone else...
    File.Delete (path);
    return true;
}
catch (IOException) {
    if (s !=null) s.Dispose ();
    return false;
}

This usually works, but I figured there'd be a better way that avoids the edge condition.

Opening the file with a DeleteOnClose flag does not work because said check (which occurs after opening with the deletion flag already set) might indicate that the file should not be deleted.

like image 363
mafu Avatar asked Aug 09 '11 15:08

mafu


2 Answers

Something like this:

    using (FileStream file = new FileStream(path,
       FileMode.Open,
       FileAccess.ReadWrite,
       FileShare.Delete))
    {
        // you can read the file here and check your stuff
        File.Delete(path);
    }

PS: note the 'using' keyword. It allows you to have a cleaner code as it takes care of Dispose calls.

like image 194
Simon Mourier Avatar answered Oct 08 '22 06:10

Simon Mourier


First of all, you're imitating "using" statement, and you're doing it the wrong way. You should Dispose the file stream just once, in the finally clause, not twice in try and catch. But, better use using.

using (FileStream s = new FileStream())
{
}

Second, you're best option is Transactional NTFS (one of the wrappers can be found in Nabu Library: https://dev.triflesoft.org/mercurial/nabu/), however Transactional NTFS is limited to NTFS and Windows Vista+, so if you need FAT16/FAT32 or Windows XP, this is not the way to go.


You can also try to move/rename opened file to disallow access by other processes, but this is limited to NTFS too AFAIR.


If you do not need a file to be deleted instantly, you can use Setup API's SetupQueueDelete function.

like image 44
adontz Avatar answered Oct 08 '22 07:10

adontz