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:
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);
}
}
}
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;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With