完結篇:展示 FileSystemFFS 在 ASP.NET 頁面中的實際調用方式、Web.config 路由配置,並修復 BlueDog 庫的 COM 物件釋放 Bug。
DateTime lastWriteTime = DateTime.Now;
// 檢查快取是否存在且未過期
bool isExists = wfs.Exists() && DateTime.Now.Subtract(lastWriteTime = wfs.GetLastWriteTime()).TotalDays <= fileKeepDays;
lastWriteTime = isExists ? lastWriteTime : DateTime.Now;
// 設定 HTTP 快取標頭
Response.Cache.SetExpires(lastWriteTime.AddDays(fileKeepDays));
Response.Cache.SetLastModified(lastWriteTime.AddMinutes(-1));
Response.ContentType = "text/Html";
if (!isExists) {
try {
writer = wfs.GetWriter();
// 此處填寫頁面內容,通常使用 XSLT 輸出
}
finally {
if (writer != null) writer.Close();
wfs.Dispose();
}
}
wfs.ResponseFile();
wfs.Dispose();
關鍵點:雙重快取驗證 (檔案存在 + 時間未過期)、正確設定 Expires/Last-Modified、確保資源釋放。
<Handler pattern="^/place/cn/((?:[^$/]+/){3})([^$]+).ASPx" handlerType="FFS" useGzip="true" savePath="/place/cn/$1FFS.resx" saveName="$2"/>
<Handler pattern="^/place/cn/([^$]+).aspx" handlerType="OS" useGzip="true" savePath="/place/cn/$1.ASPx"/>
策略:前三級行政區劃 (省/市/縣) 高頻訪問 → 直接輸出靜態檔案 (OS);第四級起 → 結構化存儲 (FFS) 按縣分檔。兼顧效能與檔案數量限制。
問題:EnumElements 取得的 ComTypes.STATSTG 及枚舉器 IEnumSTATSTG 需由 COM 釋放,否則檔案控制代洩漏,再次開啟失敗。
修正方法:在迴圈結束後呼叫 Marshal.ReleaseComObject(statstg)。
public bool IsElementExist(string elementName) {
IEnumSTATSTG statstg;
ComTypes.STATSTG stat;
uint k;
this.storage.EnumElements(0, IntPtr.Zero, 0, out statstg);
statstg.Reset();
bool found = false;
while (statstg.Next(1, out stat, out k) == HRESULT.S_OK) {
if (string.Compare(stat.pwcsName, elementName, true) == 0) { found = true; break; }
}
Marshal.ReleaseComObject(statstg); // 關鍵修復
return found;
}
public List GetChildElementsInfo() {
IEnumSTATSTG statstg;
ComTypes.STATSTG stat;
uint k;
List list = new List();
this.storage.EnumElements(0, IntPtr.Zero, 0, out statstg);
statstg.Reset();
while (statstg.Next(1, out stat, out k) == HRESULT.S_OK) {
list.Add(new StgElementInfo(stat));
}
Marshal.ReleaseComObject(statstg); // 關鍵修復
return list;
}
此 Bug 困擾許久,已回報原作者 BlueDog 修正。