大家好,我是展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源等领域有深厚造诣。
图书作者:《ESP32-C3 物联网工程开发实战》
图书作者:《SwiftUI 入门,进阶与实战》
超级个体:COC上海社区主理人
特约讲师:大学讲师,谷歌亚马逊分享嘉宾
科技博主:华为HDE/HDG
我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告,同时也会提供产品优缺点分析、横向对比,并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。
展菲:您的前沿技术领航员
👋 大家好,我是展菲!
📱 全网搜索“展菲”,即可纵览我在各大平台的知识足迹。
📣 公众号“Swift社区”,每周定时推送干货满满的技术长文,从新兴框架的剖析到运维实战的复盘,助您技术进阶之路畅通无阻。
💬 微信端添加好友“fzhanfei”,与我直接交流,不管是项目瓶颈的求助,还是行业趋势的探讨,随时畅所欲言。
📅 最新动态:2025 年 3 月 17 日
快来加入技术社区,一起挖掘技术的无限潜能,携手迈向数字化新征程!
文章目录
- 摘要
- 引言
- 鸿蒙的文件权限整体模型
- 应用沙箱机制
- 为什么鸿蒙强调沙箱
- 文件相关权限说明
- 在 module.json5 中声明权限
- 常见文件权限对照表
- 运行时权限申请流程
- 检查权限是否已经授权
- 向用户申请权限
- 文件读写 Demo
- 应用私有目录文件读写(无需权限)
- 访问公共媒体文件(需要权限)
- 实际应用场景分析
- 场景一:OTA 升级包管理
- 场景二:用户手动导入文件
- 场景三:分布式设备间文件同步
- QA 常见问题
- Q1:为什么我申请了权限还是读不到文件?
- Q2:能不能一上来就申请所有权限?
- Q3:文件路径能不能硬编码?
- 总结
摘要
在实际的鸿蒙开发中,文件读写几乎是绕不开的一件事,比如:
- 下载 OTA 升级包
- 保存拍照或截图
- 从外部导入文件
- 设备之间同步数据文件
但很多刚接触 HarmonyOS 的同学都会踩同一个坑:
权限明明写了,代码也没报错,但就是读不了文件。
根本原因就在于:
鸿蒙的文件权限模型,和 Android、传统 Linux 思维完全不一样。
这篇文章会从设计理念 → 权限声明 → 运行时授权 → 文件读写 → 实际场景,一步一步把鸿蒙的文件权限讲清楚,并配上可以直接运行的 Demo 代码。
引言
随着 HarmonyOS 进入多设备、分布式阶段,应用已经不只是“装在一台手机上跑”。
现在的常见场景是:
- 手机负责界面
- 平板负责编辑
- 手表负责控制
- 设备之间共享文件和数据
在这种情况下,如果文件权限没设计好,轻则功能不可用,重则直接审核不过。
鸿蒙在权限这块的思路很明确:
默认不让你乱访问
能不开放就不开放
能让系统托管的,开发者尽量别自己搞
理解了这个思想,后面的 API 用起来就会顺很多。
鸿蒙的文件权限整体模型
应用沙箱机制
在 HarmonyOS 中,每个应用都有一个完全隔离的私有目录:
/data/storage/el2/base/haps/your.bundle.name/这个目录的特点只有一句话:
只要是你自己的应用,随便读写,不需要任何权限。
在代码里通常这样拿:
constfilesDir=context.filesDir;这里的context一般来自EntryAbility。
这个目录非常适合:
- 缓存文件
- 配置文件
- OTA 升级包
- 临时数据
为什么鸿蒙强调沙箱
主要原因有三个:
- 防止应用互相乱读文件
- 防止恶意扫描用户隐私
- 方便系统统一回收和管理
所以如果你能把文件放在应用私有目录,基本可以避开 80% 的权限问题。
文件相关权限说明
在 module.json5 中声明权限
如果你需要访问公共目录或媒体文件,就必须在module.json5中声明权限。
示例:
{ "module": { "requestPermissions": [ { "name": "ohos.permission.READ_MEDIA", "reason": "需要读取用户选择的图片和视频文件", "usedScene": { "abilities": ["EntryAbility"], "when": "inuse" } } ] } }这里有几个点一定要注意:
reason会展示给用户看when建议用inuse- 不要乱写权限,审核会看
常见文件权限对照表
| 权限名 | 作用 |
|---|---|
| READ_MEDIA | 读取图片、视频、音频 |
| WRITE_MEDIA | 写入多媒体文件 |
| READ_USER_STORAGE | 读取用户文件 |
| WRITE_USER_STORAGE | 写入用户文件 |
实际开发中,READ_MEDIA + 文件选择器就能解决大部分问题。
运行时权限申请流程
在鸿蒙中,声明权限 ≠ 已经授权。
真正能不能用,取决于运行时。
检查权限是否已经授权
importabilityAccessCtrlfrom'@ohos.abilityAccessCtrl';constatManager=abilityAccessCtrl.createAtManager();asyncfunctioncheckPermission(context){constresult=awaitatManager.checkAccessToken(context.applicationInfo.accessTokenId,'ohos.permission.READ_MEDIA');returnresult===abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED;}这一步一般在真正读文件之前做,而不是一启动就做。
向用户申请权限
asyncfunctionrequestPermission(context){awaitatManager.requestPermissionsFromUser(context,['ohos.permission.READ_MEDIA']);}如果用户拒绝了,你的代码必须能兜底,比如:
- 弹提示
- 关闭相关功能
- 引导用户重新授权
文件读写 Demo
应用私有目录文件读写(无需权限)
importfsfrom'@ohos.file.fs';functionwritePrivateFile(context){constfilePath=context.filesDir+'/demo.txt';constfile=fs.openSync(filePath,fs.OpenMode.CREATE|fs.OpenMode.READ_WRITE);fs.writeSync(file.fd,'Hello HarmonyOS');fs.closeSync(file);}这段代码在任何设备上都能直接跑。
适合用在:
- 升级包缓存
- 日志文件
- 本地配置
访问公共媒体文件(需要权限)
importfsfrom'@ohos.file.fs';functionreadPublicFile(){consturi='file://media/Photo/test.jpg';constfile=fs.openSync(uri,fs.OpenMode.READ_ONLY);fs.closeSync(file);}如果你没申请权限,这里会直接失败。
实际应用场景分析
场景一:OTA 升级包管理
推荐方案:
- 下载到应用私有目录
- 不走公共存储
- 不申请任何文件权限
示例代码:
functiongetUpgradePath(context){returncontext.filesDir+'/upgrade/update.bin';}这样做的好处是:
- 权限最少
- 风险最低
- 稳定性最高
场景二:用户手动导入文件
这种情况最推荐用文件选择器。
importpickerfrom'@ohos.file.picker';asyncfunctionselectFile(){constphotoPicker=newpicker.PhotoViewPicker();constresult=awaitphotoPicker.select();console.info('用户选择的文件:',JSON.stringify(result));}系统会自动处理权限弹窗,你只拿结果。
场景三:分布式设备间文件同步
思路很简单:
- 文件先放私有目录
- 用分布式能力同步
- 不直接访问对方文件系统
示例路径统一:
constsyncDir=context.filesDir+'/distributed/';这样可以保证:
- 每台设备都有独立沙箱
- 不破坏系统安全模型
QA 常见问题
Q1:为什么我申请了权限还是读不到文件?
通常原因有三种:
- URI 写错
- 权限申请时机不对
- 用户拒绝了授权
建议在代码里明确判断授权结果。
Q2:能不能一上来就申请所有权限?
不建议。
鸿蒙审核更看重最小权限原则,乱申请容易被打回。
Q3:文件路径能不能硬编码?
不建议。
不同设备、系统版本路径可能不一样,优先用context.filesDir。
总结
在 HarmonyOS 中,文件权限的核心可以总结为一句话:
能用私有目录就别碰公共目录
能让系统管权限就别自己折腾
只要你记住这几个原则:
- 私有目录优先
- 权限按需申请
- 文件选择器优先
- 拒绝场景必须兜底
文件权限这一块,基本就不会再踩大坑。