Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using IDisposable to Delete a File from Disk

I have a situation where I need to save an uploaded HttpPostedFile to the server's disk, provide its full path to some code that will do something with the file on disk, then delete the file. I decided to make a proxy for working with the file. The proxy abstracts the details of saving the file to disk and deleting it once it is no longer being used. I implemented IDisposable in the proxy in order to treat the saved file like an unmanaged resource and ensure it gets deleted at some point. Of course, every time I try to implement IDisposable, I double check the pattern and discover dozens and questions and articles on the topic covering all the most complicated implementations.

I am thinking that most of these implementations are overkill for what I need, so I've implemented it much more simply. There's not much in my class; there's merely the saving of a file and a few public strings to allow access to the saved file through its file path. There's a Delete method for explicitly deleting the file and a Dispose method to call Delete if the client code doesn't. And lastly there's a finalizer that merely calls Dispose. The class is sealed. There are no members that implement IDisposable themselves. There are no considerable managed resources. In my estimation, there's no need to further meddle with Garbage Collection as the only important thing that needs to happen is the deletion of the file.

So my questions are these:

  1. Is there anything inherently wrong with dealing with saving and deleting a "temp" file in this fashion?
  2. Are there any problems with my below implementation of IDisposable, considering I don't need to bother with managed resource cleanup.

Please note that in my use case, the file must be saved to disk for another piece of code to work with it, and the file needs to be accessible using its file path, not by passing streams around or anything like that.

public sealed class TempFileProxy : IDisposable
{
    private bool disposed;

    public TempFileProxy(HttpPostedFile httpPostedFile)
    {
        this.disposed = false;
        this.FileName = httpPostedFile.FileName;
        this.Directory = AppSettings("TempFileDirectory");
        this.FullPath = $@"{this.Directory}\{this.FileName}";

        httpPostedFile.SaveAs(this.FullPath);
    }

    ~TempFileProxy()
    {
        this.Dispose();
    }

    public string FullPath { get; }

    public string Directory { get; }

    public string FileName { get; }

    public void Dispose()
    {
        if (this.disposed)
        {
            return;
        }

        this.disposed = true;
        this.Delete();
    }

    public void Delete()
    {
        if (File.Exists(this.FullPath))
        {
            File.Delete(this.FullPath);
        }
    }
}
like image 513
bubbleking Avatar asked Oct 19 '22 10:10

bubbleking


1 Answers

There is nothing wrong in deleting temporary files using IDisposable implementation. However, be more careful when deleting it - you don't want exception to be thrown during this operation (because file is in use for example). Also, suppress finalizer if you already disposed an object using regular Dispose call:

~TempFileProxy() { 
    Dispose(false);
}

public void Dispose() { 
    Dispose(true); 
}

private void Dispose(bool disposing)
{
    if (disposing)
    {
        GC.SuppressFinalize(this);                
    }
    if (this.FullPath != null)
    {
        try { 
            File.Delete(this.FullPath); 
        }
        catch { }
        this.FullPath = null;
    }
}
like image 174
Evk Avatar answered Nov 03 '22 01:11

Evk