HarmonyOS应用开发实战:猫猫大作战-沙箱路径的获取和使用 前言HarmonyOS 应用运行在沙箱环境中每个应用有自己独立的私有文件目录不能直接访问系统文件或其他应用的文件。沙箱机制保证了数据隔离性和安全性但也要求开发者正确理解filesDir、cacheDir、tempDir等不同目录的用途。在「猫猫大作战」中玩家战绩需要持久化保存filesDir排行榜缓存数据可以放在cacheDir截图等临时文件用tempDir——选错目录可能导致数据丢失或合规问题。本文以「猫猫大作战」的数据存储路径选择为锚点讲解沙箱路径的完整获取方式和各目录的最佳用途。提示本系列不讲 ArkTS 基础语法与环境搭建假设你已跟完第 1–141 篇。本篇是阶段四第 142 篇。一、沙箱路径的获取1.1 基础获取方式import { common } from kit.AbilityKit; const context getContext() as common.UIAbilityContext; // 持久化数据目录卸载时清除备份随应用 const filesDir context.filesDir; // 输出示例/data/app/el2/100/base/com.maomaodazuozhan.game/files/ // 系统缓存目录系统可自动清理 const cacheDir context.cacheDir; // 输出示例/data/app/el2/100/base/com.maomaodazuozhan.game/cache/ // 临时文件目录系统随时可清理 const tempDir context.tempDir; // 输出示例/data/app/el2/100/base/com.maomaodazuozhan.game/temp/1.2 三个目录的详细对比目录获取方式清理策略备份行为容量限制推荐用途filesDircontext.filesDir卸载时删除随应用备份无严格限制战绩、配置、用户设置cacheDircontext.cacheDir系统可自动清理不备份通常 ≤ 100MB图片缓存、网络请求缓存tempDircontext.tempDir系统随时清理不备份建议 ≤ 10MB临时下载、截图中间文件提示filesDir存储玩家不想丢失的数据如高分记录、游戏进度。cacheDir存储可重新获取的数据如头像缓存、排行榜快照。tempDir存储用完即弃的中间文件如下载中的片段。二、在游戏中的实际应用2.1 保存高分记录filesDirimport { fileIo } from kit.CoreFileKit; import { common } from kit.AbilityKit; async function saveHighScore(score: number): Promisevoid { const context getContext() as common.UIAbilityContext; const filePath ${context.filesDir}/high_score.txt; try { const file fileIo.openSync(filePath, fileIo.OpenMode.CREATE | fileIo.OpenMode.WRITE_ONLY); fileIo.writeSync(file.fd, ${score}); fileIo.closeSync(file); console.info(高分已保存: ${score}); } catch (err) { console.error(保存高分失败: ${err.message}); } } async function loadHighScore(): Promisenumber { const context getContext() as common.UIAbilityContext; const filePath ${context.filesDir}/high_score.txt; try { const file fileIo.openSync(filePath, fileIo.OpenMode.READ_ONLY); const buf new ArrayBuffer(32); fileIo.readSync(file.fd, buf); fileIo.closeSync(file); return Number(new TextDecoder().decode(buf)); } catch { return 0; // 无记录 } }2.2 缓存排行榜cacheDirasync function cacheLeaderboard(data: string): Promisevoid { const context getContext() as common.UIAbilityContext; const cachePath ${context.cacheDir}/leaderboard.json; const file fileIo.openSync(cachePath, fileIo.OpenMode.CREATE | fileIo.OpenMode.WRITE_ONLY | fileIo.OpenMode.TRUNC); fileIo.writeSync(file.fd, data); fileIo.closeSync(file); } async function readCachedLeaderboard(): Promisestring | null { const context getContext() as common.UIAbilityContext; const cachePath ${context.cacheDir}/leaderboard.json; try { const file fileIo.openSync(cachePath, fileIo.OpenMode.READ_ONLY); const stat fileIo.statSync(cachePath); const buf new ArrayBuffer(stat.size); fileIo.readSync(file.fd, buf); fileIo.closeSync(file); return new TextDecoder().decode(buf); } catch { return null; // 缓存不存在或已清理 } }三、沙箱路径的安全特性3.1 隔离性// 错误尝试访问其他应用的沙箱 const otherAppPath /data/app/el2/100/base/com.other.game/files/data.txt; fileIo.openSync(otherAppPath, fileIo.OpenMode.READ_ONLY); // ❌ 报错Permission denied // ✅ 正确只在自己的沙箱内操作 const myPath ${context.filesDir}/data.txt; fileIo.openSync(myPath, fileIo.OpenMode.CREATE | fileIo.OpenMode.READ_ONLY);3.2 路径拼接// ✅ 推荐使用完整路径拼接 const configPath ${context.filesDir}/config/game_settings.json; // ✅ 更安全使用 fileIo 的路径 API const dir fileIo.mkdirSync(${context.filesDir}/config, true); // true 递归创建 const filePath ${dir}/game_settings.json;四、文件操作模式详解// fileIo.OpenMode 的常用模式组合 const MODES { // 只读 READ: fileIo.OpenMode.READ_ONLY, // 写入覆盖 WRITE: fileIo.OpenMode.WRITE_ONLY, // 读写 READ_WRITE: fileIo.OpenMode.READ_WRITE, // 不存在则创建 CREATE: fileIo.OpenMode.CREATE, // 追加不覆盖 APPEND: fileIo.OpenMode.APPEND, // 清空再写 TRUNC: fileIo.OpenMode.TRUNC, }; // 组合使用 const OPEN_CREATE fileIo.OpenMode.CREATE | fileIo.OpenMode.WRITE_ONLY; const OPEN_READ fileIo.OpenMode.READ_ONLY;模式组合文件不存在文件已存在使用场景READ_ONLY报错正常读取读取已有配置CREATE | WRITE_ONLY创建新文件打开写入不清空追加日志CREATE | WRITE_ONLY | TRUNC创建新文件清空后写入覆盖保存READ_WRITE报错正常读写修改配置提示TRUNC标志清空文件内容——慎用会丢失已有数据。使用APPEND保留已有内容在末尾追加。五、缓存管理策略5.1 缓存有效期async function isCacheValid(cachePath: string, maxAgeMs: number): Promiseboolean { try { const stat fileIo.statSync(cachePath); const now Date.now(); const age now - stat.mtime; // 文件最后修改时间 return age maxAgeMs; } catch { return false; // 文件不存在视为过期 } } // 使用排行榜缓存 1 小时有效 const CACHE_MAX_AGE 60 * 60 * 1000; // 1 小时 const cachePath ${context.cacheDir}/leaderboard.json; if (await isCacheValid(cachePath, CACHE_MAX_AGE)) { const data await readCachedLeaderboard(); // 使用缓存数据 } else { const data await fetchLeaderboardFromServer(); await cacheLeaderboard(data); // 使用新数据 }5.2 缓存清理// 游戏启动时清理过期缓存 async function cleanExpiredCache(context: common.UIAbilityContext): Promisevoid { const cacheDir context.cacheDir; const files fileIo.listFileSync(cacheDir); const MAX_CACHE_AGE 7 * 24 * 60 * 60 * 1000; // 7 天 for (const file of files) { const filePath ${cacheDir}/${file}; try { const stat fileIo.statSync(filePath); if (Date.now() - stat.mtime MAX_CACHE_AGE) { fileIo.unlinkSync(filePath); console.info(已清理过期缓存: ${file}); } } catch (err) { console.error(清理缓存失败: ${err.message}); } } }六、目录操作6.1 递归创建目录function ensureDirExists(dirPath: string): void { try { fileIo.mkdirSync(dirPath, true); // true 递归创建父目录 } catch (err) { if (err.code ! 13900015) { // EEXIST目录已存在 throw err; } } } // 使用 const backupDir ${context.filesDir}/backups/2026/07; ensureDirExists(backupDir); // 目录不存在时自动创建backups/ → backups/2026/ → backups/2026/076.2 目录列表function listSavedGames(context: common.UIAbilityContext): string[] { const saveDir ${context.filesDir}/saves; try { const files fileIo.listFileSync(saveDir); return files.filter(f f.endsWith(.json)); } catch { return []; // saves 目录尚不存在 } }七、沙箱路径与 RDB 数据库的配合7.1 数据库位置import { relationalStore } from kit.ArkData; async function getDatabase(context: common.UIAbilityContext): PromiserelationalStore.RdbStore { const config { name: cat_game.db, // 数据库文件默认在 filesDir securityLevel: relationalStore.SecurityLevel.S1, }; // 数据库文件实际路径{filesDir}/rdb/cat_game.db const store await relationalStore.getRdbStore(context, config); return store; }7.2 数据库导出与备份async function backupDatabase(context: common.UIAbilityContext): Promisestring { const dbPath ${context.filesDir}/rdb/cat_game.db; const backupDir ${context.filesDir}/backups; ensureDirExists(backupDir); const timestamp new Date().toISOString().replace(/[:.]/g, -); const backupPath ${backupDir}/cat_game_${timestamp}.db; fileIo.copyFileSync(dbPath, backupPath); console.info(数据库已备份到: ${backupPath}); return backupPath; }八、沙箱路径与文件选择器8.1 通过 DocumentPicker 导出文件import { picker } from kit.CoreFileKit; async function exportToUserDir(context: common.UIAbilityContext, srcPath: string): Promisevoid { const documentPicker new picker.DocumentViewPicker(context); const uri await documentPicker.save({ fileType: application/json, defaultFileName: game_data_export.json, }); if (uri.length 0) { fileIo.copyFileSync(srcPath, uri[0]); console.info(文件已导出: ${uri[0]}); } }九、调试沙箱路径// 在 DevEco Studio 中使用 hdc 查看沙箱文件 // hdc shell // cd /data/app/el2/100/base/com.maomaodazhuozhan.game/files/ // ls -la // 代码内打印路径 function debugSandboxPaths(context: common.UIAbilityContext): void { console.info([Sandbox] filesDir: ${context.filesDir}); console.info([Sandbox] cacheDir: ${context.cacheDir}); console.info([Sandbox] tempDir: ${context.tempDir}); console.info([Sandbox] databaseDir: ${context.databaseDir}); console.info([Sandbox] preferencesDir: ${context.preferencesDir}); console.info([Sandbox] bundleCodeDir: ${context.bundleCodeDir}); }调试方式命令/工具用途hdc shellcd {filesDir} ls -la查看沙箱文件hdc file recvhdc file recv {remote} {local}拉取沙箱文件到电脑hdc file sendhdc file send {local} {remote}推送文件到沙箱DevEco StudioDevice File Explorer可视化浏览沙箱文件十、安全检查清单敏感数据放在filesDir而非cacheDir缓存数据设置有效期定期清理临时文件用完删除不使用硬编码的绝对路径不同设备路径不同文件操作捕获异常处理文件不存在的场景数据库文件默认在 filesDir无需手动设置路径跨应用数据共享使用 FilePicker 或 DataShare十一、版本差异API 版本沙箱路径变化影响API 9 及以下路径包含com.xxx.xxx基础沙箱API 10bundleName 替代包名路径格式调整API 11应用克隆路径隔离多用户隔离API 12加密沙箱支持数据加密存储总结HarmonyOS 沙箱路径通过context.filesDir持久、context.cacheDir缓存、context.tempDir临时三个核心入口管理应用私有文件。核心要点filesDir存玩家数据不丢失、cacheDir存可重新获取的数据、tempDir用完即弃、 文件操作捕获EEXIST/ENOENT等异常、 绝对路径因设备和版本而异、 沙箱隔离保证数据安全。下一篇将深入 JSON 序列化——stringify 与 parse 在游戏数据持久化中的应用。如果这篇文章对你有帮助欢迎点赞、收藏⭐、关注你的支持是我持续创作的动力相关资源Context 上下文 API 文档沙箱路径官方指南fileIo 文件操作 API关系型数据库 RDBDocumentPicker 文件选择器HarmonyOS 数据存储概述开源鸿蒙跨平台社区HarmonyOS 开发者官方文档第 141 篇fileIo 文件操作第 143 篇JSON 序列化