Alex Rivera | Logout

Should Dispose() or Finalize() be used to delete temporary files?

Asked 2010-07-13T19:59:04.427
21

I have a class that makes use of temporary files (Path.GetTempFileName()) while it is active. I want to make sure these files do not remain on the user's hard drive taking up space after my program is closed. Right now my class has a Close() method which checks if any temporary files used by the class still exist and deletes them.

Would it make more sense to put this code in the Dispose() or Finalize() methods instead?

Edit
Report

3 Answers

50

Better yet would be to create the file with FileOptions.DeleteOnClose. This will ensure that the operating system forcibly deletes the file when your process exits (even in the case of a rude abort). Of course, you will still want to close/delete the file yourself when you are done with it, but this provides a nice backstop to ensure that you don't allow the files to be sit around forever

Example:

using (FileStream fs = File.Create(Path.GetTempFileName(), Int16.MaxValue, 
       FileOptions.DeleteOnClose)) 
{ 

    // Use temp file 

} // The file will be deleted here
answered 2010-07-13T20:09:46.653
3

A nice way is suggested by David M. Kean on the MSDN entry on Path.GetTempFileName. He creates a wrapper class implementing IDisposable that will automatically remove the file:

public class TemporaryFile : IDisposable
{
    private bool _isDisposed;

    public bool Keep { get; set; }
    public string Path { get; private set; }

    public TemporaryFile() : this(false)
    {
    }

    public TemporaryFile(bool shortLived)
    {
        this.Path = CreateTemporaryFile(shortLived);
    }

    ~TemporaryFile()
    {
        Dispose(false);
    }

    public void Dispose()
    {
        Dispose(false);
        GC.SuppressFinalize(this);
    } 

    protected virtual void Dispose(bool disposing)
    {
        if (!_isDisposed)
        {
            _isDisposed = true;

            if (!this.Keep)
            {
                TryDelete();   
            }
        }
    }

    private void TryDelete()
    {
        try
        {
            File.Delete(this.Path);
        }
        catch (IOException)
        {
        }
        catch (UnauthorizedAccessException)
        {
        }
    }

    public static string CreateTemporaryFile(bool shortLived)
    {
        string temporaryFile = System.IO.Path.GetTempFileName();

        if (shortLived)
        { 
            // Set the temporary attribute, meaning the file will live 
            // in memory and will not be written to disk 
            //
            File.SetAttributes(temporaryFile, 
                File.GetAttributes(temporaryFile) | FileAttributes.Temporary);
        }

        return temporaryFile;
    }
}

Using the new class is easy, just type the following:

using (TemporaryFile temporaryFile = new TemporaryFile())
{
    // Use temporary file
}
answered 2010-07-13T20:23:02.190
1

You should definitely use Dispose to clean up resources, but make sure you implement the IDisposable interface. You don't want to just add a method named Dispose.

answered 2010-07-13T20:06:56.083

Your Answer