首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

Windows 8 暫存應用資料開發指南:TemporaryFolder 使用、自動清理機制與最佳實踐

     編輯:關於.NET

前言:暫存資料是應用的「草稿紙」,用完即丟,不可依賴持久性

Windows 8 `ApplicationData.TemporaryFolder` 提供應用專屬的暫存儲存區,**不參與漫遊同步**、**系統可隨時清理 (磁碟空間不足、使用者執行磁碟清理)**、**應用解除安裝時自動刪除**。適合存放:會話快取、臨時下載檔案、影像處理中間結果、離線草稿 (需配合定期存檔邏輯)。

一、核心 API 與儲存位置

  • 路徑:`%LocalAppData%\Packages\\TempState\` (實體路徑隱藏,勿硬編碼)。
  • 取得 StorageFolder:`Windows.Storage.ApplicationData.Current.TemporaryFolder`。
  • 配額**:無固定上限,受系統磁碟總配額限制。系統會優先清理最舊/最大的暫存檔案。

二、基本讀寫操作 (非同步 API)

1. 寫入暫存檔案


using Windows.Storage;
using Windows.Globalization.DateTimeFormatting;

private async void WriteTimestamp() {
    var tempFolder = ApplicationData.Current.TemporaryFolder;
    
    // 建立/取代檔案
    StorageFile file = await tempFolder.CreateFileAsync(
        "session_draft.txt", 
        CreationCollisionOption.ReplaceExisting);
    
    // 寫入文字 (支援 Unicode)
    var formatter = new DateTimeFormatter("longtime");
    string content = $"草稿儲存時間: {formatter.Format(DateTime.Now)}";
    await FileIO.WriteTextAsync(file, content);
    
    // 或寫入二進位資料
    // byte[] buffer = ...; await FileIO.WriteBytesAsync(file, buffer);
}

2. 讀取暫存檔案


private async void ReadTimestamp() {
    var tempFolder = ApplicationData.Current.TemporaryFolder;
    try {
        StorageFile file = await tempFolder.GetFileAsync("session_draft.txt");
        string content = await FileIO.ReadTextAsync(file);
        // 還原草稿內容至 UI
        DraftTextBox.Text = content;
    } catch (FileNotFoundException) {
        // 檔案不存在 (可能被系統清理、首次執行)
        // 初始化空白草稿
    } catch (Exception ex) {
        // 其他錯誤 (權限、磁碟損壞)
    }
}

3. 列舉/清理暫存資料夾


// 列舉所有檔案
IReadOnlyList files = await tempFolder.GetFilesAsync();
foreach (var f in files) { /* 處理 */ }

// 刪除特定檔案
await file.DeleteAsync(StorageDeleteOption.PermanentDelete);

// 一次清空整個暫存資料夾 (謹慎使用)
IReadOnlyList allFiles = await tempFolder.GetFilesAsync();
foreach (var f in allFiles) await f.DeleteAsync();
IReadOnlyList subFolders = await tempFolder.GetFoldersAsync();
foreach (var f in subFolders) await f.DeleteAsync();

三、系統自動清理機制:開發者必須知道的「不可靠」真相

  1. 磁碟空間壓力清理:當系統磁碟剩餘空間低於閾值 (約 10-15%),`StorageSense` / `Automatic Maintenance` 會掃描所有應用 `TempState` 資料夾,**依最後存取時間 (LRU) 刪除檔案**,直到釋放足夠空間。
  2. 使用者手動清理**:設定 → 系統 → 儲存體 → 暫存檔案 → `清理` / 執行 `cleanmgr` (磁碟清理) → 勾選 `暫存檔案` → **所有應用暫存資料一鍵清空**。
  3. 應用更新/重裝**:舊版本暫存資料**不保證保留** (視部署管道而定,MSIX 通常保留,AppX 可能清理)。
  4. 應用解除安裝**:`TempState` 資料夾連同 `LocalState`、`RoamingState` **全部永久刪除**。

四、最佳實踐設計模式

模式 1:會話級快取 (Session Cache) - 最標準用法


// 應用啟動/頁面載入時嘗試讀取
protected override async void OnNavigatedTo(NavigationEventArgs e) {
    await LoadDraftAsync(); // 從 TemporaryFolder 還原
}

// 使用者編輯時定期自動存檔 (防止意外關閉/掛起遺失)
private async void OnTextChanged(object sender, TextChangedEventArgs e) {
    if (_autoSaveTimer == null) _autoSaveTimer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(30) };
    _autoSaveTimer.Tick += async (s, _) => await SaveDraftAsync();
    _autoSaveTimer.Start();
}

// 掛起時強制存檔 (雖然 TemporaryFolder 可能被清理,但掛起期間通常安全)
private async void OnSuspending(object sender, SuspendingEventArgs e) {
    var deferral = e.SuspendingOperation.GetDeferral();
    await SaveDraftAsync(); // 同步寫入 TemporaryFolder
    deferral.Complete();
}

模式 2:大型中間檔案處理管線 (影像/影片/壓縮)


// 步驟 1: 下載/產生原始檔 → TemporaryFolder
StorageFile rawFile = await tempFolder.CreateFileAsync("raw_input.dat");
await DownloadToFileAsync(url, rawFile);

// 步驟 2: 讀取 → 處理 (解碼/濾鏡/轉碼) → 寫入中間檔 (同 TemporaryFolder)
StorageFile intermediateFile = await tempFolder.CreateFileAsync("intermediate.jpg");
await ProcessImageAsync(rawFile, intermediateFile);

// 步驟 3: 最终結果 → 移動至 LocalFolder 永久保存 / 上傳雲端 / 分享
StorageFile finalFile = await intermediateFile.MoveAsync(
    ApplicationData.Current.LocalFolder, 
    "final_result.jpg", 
    NameCollisionOption.ReplaceExisting);

// 步驟 4: 清理暫存檔 (釋放空間)
await rawFile.DeleteAsync();
await intermediateFile.DeleteAsync();

模式 3:離線優先草稿 (Offline-First Draft) - 配合 LocalFolder 雙重備份


// 核心邏輯:暫存資料夾 = 高頻寫入/讀取 (效能最佳,SSD 友善)
//           本地資料夾 = 低頻備份/持久化 (生存保障)

private async Task SaveDraftAsync(string content) {
    // 1. 立即寫入 TemporaryFolder (快速、非阻塞)
    await WriteToTempAsync("draft.txt", content);
    
    // 2. 背景低優先度備份至 LocalFolder (防止系統清理)
    _ = Task.Run(async () => {
        await Task.Delay(TimeSpan.FromMinutes(5)); // 延後批次備份
        await WriteToLocalAsync("draft_backup.txt", content);
    });
}

private async Task LoadDraftAsync() {
    // 優先嘗試 TemporaryFolder (最新)
    string content = await ReadFromTempAsync("draft.txt");
    if (string.IsNullOrEmpty(content)) {
        // 回退讀取 LocalFolder 備份
        content = await ReadFromLocalAsync("draft_backup.txt");
    }
    // 還原 UI
}

五、TemporaryFolder vs LocalFolder vs RoamingFolder 對照表

特性TemporaryFolderLocalFolderRoamingFolder
持久性低 (系統隨時清理)高 (僅應用解除安裝刪除)高 (雲端漫遊,裝置間同步)
漫遊同步否否是 (≤ 100KB/應用)
效能 (SSD)最佳 (系統優化暫存 I/O)標準標準 (+雲端同步延遲)
適用場景快取、中間檔、會話草稿使用者文件、設定、資料庫、永久資產偏好設定、遊戲進度、小型跨裝置資料
配額動態 (系統管理)靜態 (磁碟配額)嚴格 100KB

六、常見錯誤與避坑

  1. 將關鍵使用者資料 (文檔、設定、購買記錄) 存入 TemporaryFolder → 系統清理導致資料永久遺失 → 使用者投訴/流失。**鐵律:使用者可感知的資產 必須進 LocalFolder/RoamingFolder/雲端。**
  2. 假設 TemporaryFolder 檔案「通常」存在** → 讀取時未處理 `FileNotFoundException` → 應用啟動崩潰。**永遠 try-catch 處理缺失情況。**
  3. 大量暫存檔案未清理** → 佔用使用者磁碟空間 → 觸發系統清理 → 應用被標記為「佔用空間大」 → 使用者手動清理/解除安裝。**實作處理完成後立即刪除、或設定背景清理任務。**
  4. 在背景任務中直接讀寫 TemporaryFolder 而未申請 `FileAccessCache`** → 權限失敗。**背景任務存取應用資料夾需透過 `StorageApplicationPermissions.FutureAccessList` 保留存取權。**

總結

`TemporaryFolder` 是高效能、免管理配額、自動清理的**暫存專用區**。核心心法:**「寫得快、讀得快、丟得快、不心疼」**。將會話草稿、中間運算檔案、可重新產生的快取資料放入此處,配合 `LocalFolder` 關鍵節點備份策略,即能兼顧效能與資料安全,讓應用在資源受限環境下依然輕快穩定。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved