Quantcast
Channel: 黑暗執行緒
Viewing all articles
Browse latest Browse all 2311

小技巧-自動刪除App_Data過期暫存檔

$
0
0

寫網站時有時需要產生暫存檔,過去我慣用的做法是透過System.IO.Path.GetTempPath(),將暫存檔寫入Windows系統暫存資料夾,如意算盤是暫存資料夾本來就是放暫存檔的地方,而Windows有機制可在磁碟空間不足時刪除暫存檔釋放空間,如果檔案沒有機密或敏感性,放在暫存資料夾基本上可以Fire and Forget,用過就放著不管,很省事。

後來幾次部署經驗告訴我,「ASP.NET程式不一定有寫入暫存資料夾的權限」(登楞!)。針對Temp資料夾開放ASP.NET寫入權限是一種解法,但每個ASP.NET應用程式的執行身分不同,搞下來Temp資料夾需維護一堆權限有點複雜。相形之下,App_Data隸屬各ASP.NET應用程式,可部署時一併設定權限統一管理,相對簡便。(註:適合放暫存檔是因為App_Data具有隱身特性,請不要將暫存檔放在一般網站目錄下,以免被使用者不當存取)

但暫存檔放App_Data就不像系統暫存資料夾可以靠Windows機制回收空間,得自行清理過期暫存檔。最直覺做法是寫個排程每天定時刪檔,但最近我想出另一個更省事的做法-取得暫存目錄時自動清理過期檔案。程式範例如下,分享兼請大家Code Review:P

//記憶上次清理執行日期
staticstring lastAttTempCleanDate = null;
//非同步鎖定
staticobject cleanLock = new Object();
 
staticstring GetTempPath()
    {
//使用App_Data暫存檔案,避免ASPX沒有寫入系統TEMP權限
string tempPath = Path.Combine(
            HttpContext.Current.Server.MapPath("~/App_Data"), "UploadAtts");
//若目錄不存在,建立之
        Directory.CreateDirectory(tempPath);
//每次啟動網站或每天清理一次過期Cache
string todayDate = DateTime.Today.ToString("yyyyMMdd");
//防止多執行緒同時觸發
lock (cleanLock)
        {
//比對上次執行日期,原則上每天只執行一次
if (todayDate != lastAttTempCleanDate)
            {
//先儲存執行日期記錄,避免重複執行
                lastAttTempCleanDate = todayDate;
//另開Thread執行刪除,以免卡住目前的暫存作業
                Task.Factory.StartNew(() =>
                {
//決定逾期判斷基準
                    DateTime expireTime = DateTime.Today;
foreach (var file in Directory.GetFiles(tempPath))
                    {
//若檔案建立時間早於今天,刪除之
if (File.GetCreationTime(file).CompareTo(expireTime) == -1)
                        {
                            File.Delete(file);
                        }
                    }
                });
            }
        }
return tempPath;
    }

Viewing all articles
Browse latest Browse all 2311

Trending Articles