一个处理临时文件的简单技术(提示:Windows 不会自动为您处理)






4.33/5 (7投票s)
这是一种简单而巧妙的方法,我想出了即使在我忘记它们很久之后也能删除临时文件的方法。
介绍/背景
大家好!
两天前,我正在开发一个复杂的 ASP.NET 上传模块。(实际上,我是在这个未完成的上传模块的基础上进行开发的 - http://darrenjohnstone.net。)
我更改了代码,使其能够自动找出 Windows 临时文件夹的位置,通过多种方式实现故障安全,然后将文件上传到该文件夹的一个子文件夹中,并使用 GUID 为其指定一个随机名称。到目前为止 - 一切都很好。
现在,一直困扰我的是 - 临时文件会发生什么情况?
您要知道,Windows 不会以**任何**方式管理临时文件夹。 它永远不会自行删除文件。 在临时文件中弄脏东西的应用程序必须在事后自行清理。
所以我提供了一个 "MoveTo" 函数,将文件移动到目标位置(而不是复制,这会浪费资源)。 这样,如果文件被处理,就不会在临时文件中留下任何东西。 但是,如果没有代码处理上传的文件怎么办? 或者出现错误? 文件可能会在当前上下文中的任何位置被处理或不被处理,并且我无法跟踪/控制会发生什么。
然后我想出了一个简单的解决方案:一个删除器类。
它实际上非常简单
- 它包含要删除的文件的完整本地路径。
- 它实现了一个正确的 dispose 模式,它会释放文件本身。
- 它实现了一个 "Cancel" 删除的方法。
好的,我将写下我编写的代码,但我不会编写任何关于上传机制的内容,因为它是一个无关的问题,并且这个 "deleter" 类与许多其他情况相关。
Using the Code
这是代码
public class TemporaryFileDeleter : IDisposable
{
private string _LocalFilePath;
public string LocalFilePath
{
get { return _LocalFilePath; }
}
public TemporaryFileDeleter(string localFilePath)
{
_LocalFilePath = localFilePath;
}
~TemporaryFileDeleter()
{
Dispose(false);
}
public void DeleteFile()
{
string path = _LocalFilePath;
_LocalFilePath = null;
if (path == null) return;
System.IO.File.Delete(path);
}
public void DoNotDelete()
{
_LocalFilePath = null;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
}
// Now clean up Native Resources
try
{
DeleteFile();
}
catch { }
}
}
如果您不熟悉 .NET 的 disposing 机制,最好先研究一下,这样您才能了解这里发生了什么。(它实际上非常简单。)
这里发生的是,只有当这个类被 disposed 时,它才会尝试删除该文件。
所以,如果我创建了一个临时文件,并且我想稍后删除它,我将像这样创建这个类的一个实例
deleter = new TemporaryFileDeleter("C:\Windows\Temp\1234.dat");
但是,如果我决定保留该文件(或者防止它尝试删除我已经移动的文件,以防使用 "MoveTo" 函数),我可以调用: deleter.DoNotDelete()
。
如果我再次使用文件上传模块的示例,那么它是这样的:我为每个 FileUpload
(派生)控件创建一个单独的 "File processor" 类,并且该类尝试创建临时文件并将数据流式传输到文件中。 但是,在创建文件之后,在开始流式传输之前,它将创建 TemporaryFileDeleter
的一个实例,并将其作为成员变量分配给处理器类。.NET 框架的垃圾回收器只会在 FileUpload
控件被销毁后才敢销毁/释放处理器类,这意味着在请求完成后。 只有到那时,它才会尝试释放 TemporaryFileDeleter
类并实际删除该文件。
如果在任何时候出现严重错误,也没关系,因为即使 IIS 意外终止,它仍然会尝试释放对象并杀死该文件! 我做了一些测试并导致 IIS 崩溃 - 临时文件仍然被删除。
注意:即使您没有立即看到文件被删除,它也可能会在接下来的 2-3 分钟内发生。 垃圾回收器以神秘的方式(聪明的方式)工作,它会在它想要的时候杀死该文件。
关注点
一个有趣的点,或者一个让你发疯的点是,微软从未为 Windows 实现任何垃圾回收器... 为什么我总是必须清理其他应用程序和 Windows 自身? 如果决定 Windows 在每次重新启动时(或者可能在第二次重新启动时,以允许旧版支持在下次重新启动之前保留临时文件的安装程序)清理 Temp 文件夹中的文件,这将非常简单。 甚至可以使用一种方法向 Windows "注册" 一个临时文件,以便稍后使用一些规则进行删除。 但是**没有**! 从未听说过这种事情...
希望我能帮助到大家!
历史
还没有...