使用 IDisposable 从磁盘中删除文件
Using IDisposable to Delete a File from Disk
我遇到这样一种情况,我需要将上传的 HttpPostedFile
保存到服务器的磁盘,将其完整路径提供给将对磁盘上的文件执行某些操作的一些代码,然后删除该文件。我决定制作一个代理来处理该文件。代理抽象了将文件保存到磁盘并在不再使用时将其删除的细节。我在代理中实现了 IDisposable,以便将保存的文件视为非托管资源,并确保它在某个时候被删除。当然,每次我尝试实现 IDisposable 时,我都会仔细检查模式并发现数十个关于该主题的问题和文章,涵盖所有最复杂的实现。
我认为这些实现中的大多数对于我需要的东西来说都过分了,所以我实现得更简单了。我的 class; 里没有多少东西;仅保存一个文件和一些 public 字符串以允许通过其文件路径访问保存的文件。有一个用于显式删除文件的 Delete 方法和一个用于调用 Delete 的 Dispose 方法(如果客户端代码没有删除)。最后还有一个仅调用 Dispose 的终结器。 class 是密封的。没有自己实现 IDisposable 的成员。没有可观的托管资源。据我估计,没有必要进一步干预垃圾收集,因为唯一需要做的重要事情就是删除文件。
所以我的问题是:
- 以这种方式保存和删除 "temp" 文件有什么本质上的错误吗?
- 我下面的 IDisposable 实现是否有任何问题,考虑到我不需要为托管资源清理而烦恼。
请注意,在我的用例中,文件必须保存到磁盘以便另一段代码使用它,并且文件需要可以使用其文件路径访问,而不是通过传递流或类似的东西那。
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);
}
}
}
使用 IDisposable 实现删除临时文件没有错。但是,删除它时要更加小心 - 您不希望在此操作期间抛出异常(例如,因为文件正在使用中)。此外,如果您已经使用常规 Dispose 调用处理了一个对象,请抑制终结器:
~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;
}
}
我这里有几个问题:
1) 我遇到了 File.Exists 在某些外部设备上失败的问题。我已经到了我只是尝试使用该文件并在抛出异常时捕获异常的地步。
2) File.Delete 可以扔。
2a) 该文件正在被某物使用。
2b) 留下了一把幻影锁。 (Windows 8 XPS 查看器,我在看你!)
2c) 网络问题。
我遇到这样一种情况,我需要将上传的 HttpPostedFile
保存到服务器的磁盘,将其完整路径提供给将对磁盘上的文件执行某些操作的一些代码,然后删除该文件。我决定制作一个代理来处理该文件。代理抽象了将文件保存到磁盘并在不再使用时将其删除的细节。我在代理中实现了 IDisposable,以便将保存的文件视为非托管资源,并确保它在某个时候被删除。当然,每次我尝试实现 IDisposable 时,我都会仔细检查模式并发现数十个关于该主题的问题和文章,涵盖所有最复杂的实现。
我认为这些实现中的大多数对于我需要的东西来说都过分了,所以我实现得更简单了。我的 class; 里没有多少东西;仅保存一个文件和一些 public 字符串以允许通过其文件路径访问保存的文件。有一个用于显式删除文件的 Delete 方法和一个用于调用 Delete 的 Dispose 方法(如果客户端代码没有删除)。最后还有一个仅调用 Dispose 的终结器。 class 是密封的。没有自己实现 IDisposable 的成员。没有可观的托管资源。据我估计,没有必要进一步干预垃圾收集,因为唯一需要做的重要事情就是删除文件。
所以我的问题是:
- 以这种方式保存和删除 "temp" 文件有什么本质上的错误吗?
- 我下面的 IDisposable 实现是否有任何问题,考虑到我不需要为托管资源清理而烦恼。
请注意,在我的用例中,文件必须保存到磁盘以便另一段代码使用它,并且文件需要可以使用其文件路径访问,而不是通过传递流或类似的东西那。
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);
}
}
}
使用 IDisposable 实现删除临时文件没有错。但是,删除它时要更加小心 - 您不希望在此操作期间抛出异常(例如,因为文件正在使用中)。此外,如果您已经使用常规 Dispose 调用处理了一个对象,请抑制终结器:
~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;
}
}
我这里有几个问题:
1) 我遇到了 File.Exists 在某些外部设备上失败的问题。我已经到了我只是尝试使用该文件并在抛出异常时捕获异常的地步。
2) File.Delete 可以扔。 2a) 该文件正在被某物使用。 2b) 留下了一把幻影锁。 (Windows 8 XPS 查看器,我在看你!) 2c) 网络问题。