ASP.NET计划删除临时文件

问题:我有一个ASP.NET应用程序,可以创建临时PDF文件(供用户下载)。 现在,许多用户在很多天内都可以创建许多PDF,这需要占用大量磁盘空间。

安排删除超过1天/ 8小时的文件的最佳方法是什么? 最好是在asp.net应用程序本身…

对于您需要创建的每个临时文件,请在会话中记下文件名:

// create temporary file: string fileName = System.IO.Path.GetTempFileName(); Session[string.Concat("temporaryFile", Guid.NewGuid().ToString("d"))] = fileName; // TODO: write to file 

接下来,将以下清理代码添加到global.asax:

 <%@ Application Language="C#" %>  

更新 :我现在正在使用一种新的(改进的)方法,而不是上面描述的方法。 新的涉及HttpRuntime.Cache并检查文件是否超过8小时。 如果有兴趣的话,我会在这里发布。 这是我的新global.asax.cs

 using System; using System.Web; using System.Text; using System.IO; using System.Xml; using System.Web.Caching; public partial class global : System.Web.HttpApplication { protected void Application_Start() { RemoveTemporaryFiles(); RemoveTemporaryFilesSchedule(); } public void RemoveTemporaryFiles() { string pathTemp = "d:\\uploads\\"; if ((pathTemp.Length > 0) && (Directory.Exists(pathTemp))) { foreach (string file in Directory.GetFiles(pathTemp)) { try { FileInfo fi = new FileInfo(file); if (fi.CreationTime < DateTime.Now.AddHours(-8)) { File.Delete(file); } } catch (Exception) { } } } } public void RemoveTemporaryFilesSchedule() { HttpRuntime.Cache.Insert("RemoveTemporaryFiles", string.Empty, null, DateTime.Now.AddHours(1), Cache.NoSlidingExpiration, CacheItemPriority.NotRemovable, delegate(string id, object o, CacheItemRemovedReason cirr) { if (id.Equals("RemoveTemporaryFiles", StringComparison.OrdinalIgnoreCase)) { RemoveTemporaryFiles(); RemoveTemporaryFilesSchedule(); } }); } } 

尝试使用Path.GetTempPath() 。 它将为您提供Windows临时文件夹的路径。 然后它将取决于窗户清理:)

你可以在这里阅读更多关于这个方法的信息http://msdn.microsoft.com/en-us/library/system.io.path.gettemppath.aspx

最好的方法是创建一个批处理文件,由Windows任务调度程序以您想要的间隔调用该文件。

要么

您可以使用上面的类创建一个Windows服务

 public class CleanUpBot { public bool KeepAlive; private Thread _cleanUpThread; public void Run() { _cleanUpThread = new Thread(StartCleanUp); } private void StartCleanUp() { do { // HERE THE LOGIC FOR DELETE FILES _cleanUpThread.Join(TIME_IN_MILLISECOND); }while(KeepAlive) } } 

请注意,您也可以在pageLoad中调用此类,它不会影响处理时间,因为处理是在另一个线程中。 只需删除do-while和Thread.Join()。

你如何存储文件? 如果可能,您可以使用简单的解决方案,其中所有文件都存储在以当前日期和时间命名的文件夹中。
然后创建一个将删除旧文件夹的简单页面或httphandler。 您可以使用Windows计划或其他cron作业定期调用此页面。

在Appication_Start上创建一个计时器,并安排计时器每隔1小时调用一个方法,并刷新超过8小时或1天的文件或您需要的任何持续时间。

我有点同意德克在答案中说的最新情况。

想法是将文件放到其中的临时文件夹是一个固定的已知位置,但我略有不同……

  1. 每次创建文件时都会将文件名添加到会话对象中的列表中(假设没有数千个,如果此列表遇到给定的上限,则执行下一个位)

  2. 当会话结束时,应该在global.asax中引发Session_End事件。 迭代列表中的所有文件并将其删除。

  private const string TEMPDIRPATH = @"C:\\mytempdir\"; private const int DELETEAFTERHOURS = 8; private void cleanTempDir() { foreach (string filePath in Directory.GetFiles(TEMPDIRPATH)) { FileInfo fi = new FileInfo(filePath); if (!(fi.LastWriteTime.CompareTo(DateTime.Now.AddHours(DELETEAFTERHOURS * -1)) <= 0)) //created or modified more than x hours ago? if not, continue to the next file { continue; } try { File.Delete(filePath); } catch (Exception) { //something happened and the file probably isn't deleted. the next time give it another shot } } } 

上面的代码将删除临时目录中超过8小时前创建或修改的文件。

不过我建议使用另一种方法。 正如Fredrik Johansson建议的那样,您可以在会话结束时删除用户创建的文件。 最好是根据临时目录中用户的会话ID使用额外的目录。 会话结束时,只需删除为用户创建的目录。

  private const string TEMPDIRPATH = @"C:\\mytempdir\"; string tempDirUserPath = Path.Combine(TEMPDIRPATH, HttpContext.Current.User.Identity.Name); private void removeTempDirUser(string path) { try { Directory.Delete(path); } catch (Exception) { //an exception occured while deleting the directory. } } 

使用缓存过期通知来触发文件删除:

  private static void DeleteLater(string path) { HttpContext.Current.Cache.Add(path, path, null, Cache.NoAbsoluteExpiration, new TimeSpan(0, 8, 0, 0), CacheItemPriority.NotRemovable, UploadedFileCacheCallback); } private static void UploadedFileCacheCallback(string key, object value, CacheItemRemovedReason reason) { var path = (string) value; Debug.WriteLine(string.Format("Deleting upladed file '{0}'", path)); File.Delete(path); } 

ref: MSDN | 如何:从缓存中删除项目时通知应用程序