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 序列化

相关新闻

如何快速制作集成最新补丁的Windows安装镜像:终极自动化方案

如何快速制作集成最新补丁的Windows安装镜像:终极自动化方案

如何快速制作集成最新补丁的Windows安装镜像:终极自动化方案 【免费下载链接】Win_ISO_Patching_Scripts Win_ISO_Patching_Scripts 项目地址: https://gitcode.com/gh_mirrors/wi/Win_ISO_Patching_Scripts 想要为Windows系统部署准备一个包含所有最新安全补…

2026/7/29 14:39:42 阅读更多 →
零样本语音克隆技术:1分钟实现高拟真声音合成

零样本语音克隆技术:1分钟实现高拟真声音合成

1. 项目概述:一分钟实现零样本声音克隆的技术突破 这个开源项目实现了一个惊人的能力——只需1分钟音频样本,就能训练出高度拟真的个性化语音合成模型。作为从业多年的语音技术开发者,我亲测其效果已经达到商用级水平。传统TTS系统需要数小时…

2026/7/29 14:39:42 阅读更多 →
AIGC论文检测与降重策略:2026学术规范应对指南

AIGC论文检测与降重策略:2026学术规范应对指南

1. 博士论文AIGC痕迹检测现状与挑战 2026年的学术环境对论文原创性提出了前所未有的严格要求。全球主要学术机构已普遍采用第四代AI检测系统,其核心算法结合了语义指纹分析、写作风格识别和内容溯源技术。以Turnitin的GenAI Detector 4.0为例,系统不仅能…

2026/7/29 14:39:42 阅读更多 →

最新新闻

如何用Sketch MeaXure在5分钟内完成设计标注:告别手动测量的新时代

如何用Sketch MeaXure在5分钟内完成设计标注:告别手动测量的新时代

如何用Sketch MeaXure在5分钟内完成设计标注:告别手动测量的新时代 【免费下载链接】sketch-meaxure 项目地址: https://gitcode.com/gh_mirrors/sk/sketch-meaxure 你是否曾在设计稿和开发实现之间反复沟通,因为标注不清晰而浪费宝贵时间&#…

2026/7/29 14:49:47 阅读更多 →
终极指南:在Mac上使用alt-tab-macos实现高效窗口切换

终极指南:在Mac上使用alt-tab-macos实现高效窗口切换

终极指南:在Mac上使用alt-tab-macos实现高效窗口切换 【免费下载链接】alt-tab-macos Windows alt-tab on macOS 项目地址: https://gitcode.com/gh_mirrors/al/alt-tab-macos 想要在Mac上获得Windows风格的AltTab窗口切换体验吗?alt-tab-macos就…

2026/7/29 14:49:47 阅读更多 →
开源权重模型本地部署指南:硬件要求、API集成与批量任务实战

开源权重模型本地部署指南:硬件要求、API集成与批量任务实战

开源权重模型最近在技术圈引发了不少讨论,特别是关于其商业价值、技术门槛和行业影响的争议。这次我们直接来看行业领袖们的最新发声,他们从技术可行性、部署成本、实际应用场景等角度,对当前的开源模型争议给出了明确回应。 如果你关心本地…

2026/7/29 14:49:47 阅读更多 →
终极防撤回指南:3分钟掌握微信QQ消息保护技巧

终极防撤回指南:3分钟掌握微信QQ消息保护技巧

终极防撤回指南:3分钟掌握微信QQ消息保护技巧 【免费下载链接】RevokeMsgPatcher :trollface: A hex editor for WeChat/QQ/TIM - PC版微信/QQ/TIM防撤回补丁(我已经看到了,撤回也没用了) 项目地址: https://gitcode.com/GitHub…

2026/7/29 14:49:47 阅读更多 →
NBTExplorer:如何快速掌握Minecraft数据编辑的终极免费工具

NBTExplorer:如何快速掌握Minecraft数据编辑的终极免费工具

NBTExplorer:如何快速掌握Minecraft数据编辑的终极免费工具 【免费下载链接】NBTExplorer A graphical NBT editor for all Minecraft NBT data sources 项目地址: https://gitcode.com/gh_mirrors/nb/NBTExplorer NBTExplorer是一款专门为Minecraft玩家和开…

2026/7/29 14:49:47 阅读更多 →
如何用Locale Remulator系统区域语言模拟器彻底解决64位应用乱码问题

如何用Locale Remulator系统区域语言模拟器彻底解决64位应用乱码问题

如何用Locale Remulator系统区域语言模拟器彻底解决64位应用乱码问题 【免费下载链接】Locale_Remulator System Region and Language Simulator. 项目地址: https://gitcode.com/gh_mirrors/lo/Locale_Remulator 你是否遇到过这样的困扰:下载了最新的海外游…

2026/7/29 14:48:47 阅读更多 →

日新闻

【RT-DETR多模态创新改进】CVPR 2025 | 独家特征融合创新改进篇 | 引入RLAB残差线性注意力模块,有效融合并强调多尺度特征,多种改进点,适合红外与可见光融合目标检测任务,有效涨点

【RT-DETR多模态创新改进】CVPR 2025 | 独家特征融合创新改进篇 | 引入RLAB残差线性注意力模块,有效融合并强调多尺度特征,多种改进点,适合红外与可见光融合目标检测任务,有效涨点

一、本文介绍 🔥本文在RT-DETR多模态融合目标检测中引入RLAB残差线性注意力模块,可在不同模态特征交互阶段进行多次残差细化,使可见光、红外等特征在尺度、语义和空间位置上更好对齐;随后将细化特征与解码器输出拼接并生成Q、K、V,通过线性注意力自适应强化关键通道、目…

2026/7/29 0:00:23 阅读更多 →
AI编程系列02:合并知识功能,给 AI 问数和 RAG 场景打基础

AI编程系列02:合并知识功能,给 AI 问数和 RAG 场景打基础

AI编程系列02:合并知识功能,给 AI 问数和 RAG 场景打基础 在上一期「AI编程系列」中,我们学习了如何构建一个基础的 AI 问答系统,通过简单的输入输出让模型回应问题。但现实世界中的 AI 应用往往需要处理更复杂的场景:…

2026/7/29 0:00:23 阅读更多 →
AI智能体开发实战:从工具调用到企业级部署

AI智能体开发实战:从工具调用到企业级部署

1. 从被动问答到主动执行:AI Agent的范式转变过去两年,大语言模型最显著的应用形态是聊天机器人——用户提问,AI回答。但真正的生产力革命发生在2023年下半年:当AI学会主动调用工具完成任务时,生产力工具的历史被彻底改…

2026/7/29 0:00:23 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/28 12:04:22 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/29 14:34:28 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/28 5:03:42 阅读更多 →

月新闻