在这里插入图片描述

网罗开发 (小红书、快手、视频号同名)

  大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源等领域有深厚造诣。

图书作者:《ESP32-C3 物联网工程开发实战》
图书作者:《SwiftUI 入门,进阶与实战》
超级个体:COC上海社区主理人
特约讲师:大学讲师,谷歌亚马逊分享嘉宾
科技博主:华为HDE/HDG

我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告,同时也会提供产品优缺点分析、横向对比,并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。

展菲:您的前沿技术领航员
👋 大家好,我是展菲!
📱 全网搜索“展菲”,即可纵览我在各大平台的知识足迹。
📣 公众号“Swift社区”,每周定时推送干货满满的技术长文,从新兴框架的剖析到运维实战的复盘,助您技术进阶之路畅通无阻。
💬 微信端添加好友“fzhanfei”,与我直接交流,不管是项目瓶颈的求助,还是行业趋势的探讨,随时畅所欲言。
📅 最新动态:2025 年 3 月 17 日
快来加入技术社区,一起挖掘技术的无限潜能,携手迈向数字化新征程!


摘要

在实际的鸿蒙开发中,文件读写几乎是绕不开的一件事,比如:

  • 下载 OTA 升级包
  • 保存拍照或截图
  • 从外部导入文件
  • 设备之间同步数据文件

但很多刚接触 HarmonyOS 的同学都会踩同一个坑:

权限明明写了,代码也没报错,但就是读不了文件。

根本原因就在于:
鸿蒙的文件权限模型,和 Android、传统 Linux 思维完全不一样。

这篇文章会从设计理念 → 权限声明 → 运行时授权 → 文件读写 → 实际场景,一步一步把鸿蒙的文件权限讲清楚,并配上可以直接运行的 Demo 代码。

引言

随着 HarmonyOS 进入多设备、分布式阶段,应用已经不只是“装在一台手机上跑”。

现在的常见场景是:

  • 手机负责界面
  • 平板负责编辑
  • 手表负责控制
  • 设备之间共享文件和数据

在这种情况下,如果文件权限没设计好,轻则功能不可用,重则直接审核不过。

鸿蒙在权限这块的思路很明确:

默认不让你乱访问
能不开放就不开放
能让系统托管的,开发者尽量别自己搞

理解了这个思想,后面的 API 用起来就会顺很多。

鸿蒙的文件权限整体模型

应用沙箱机制

在 HarmonyOS 中,每个应用都有一个完全隔离的私有目录

/data/storage/el2/base/haps/your.bundle.name/

这个目录的特点只有一句话:

只要是你自己的应用,随便读写,不需要任何权限。

在代码里通常这样拿:

const filesDir = context.filesDir;

这里的 context 一般来自 EntryAbility

这个目录非常适合:

  • 缓存文件
  • 配置文件
  • OTA 升级包
  • 临时数据

为什么鸿蒙强调沙箱

主要原因有三个:

  1. 防止应用互相乱读文件
  2. 防止恶意扫描用户隐私
  3. 方便系统统一回收和管理

所以如果你能把文件放在应用私有目录,基本可以避开 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 + 文件选择器就能解决大部分问题。

运行时权限申请流程

在鸿蒙中,声明权限 ≠ 已经授权
真正能不能用,取决于运行时。

检查权限是否已经授权

import abilityAccessCtrl from '@ohos.abilityAccessCtrl';

const atManager = abilityAccessCtrl.createAtManager();

async function checkPermission(context) {
  const result = await atManager.checkAccessToken(
    context.applicationInfo.accessTokenId,
    'ohos.permission.READ_MEDIA'
  );
  return result === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED;
}

这一步一般在真正读文件之前做,而不是一启动就做。

向用户申请权限

async function requestPermission(context) {
  await atManager.requestPermissionsFromUser(
    context,
    ['ohos.permission.READ_MEDIA']
  );
}

如果用户拒绝了,你的代码必须能兜底,比如:

  • 弹提示
  • 关闭相关功能
  • 引导用户重新授权

文件读写 Demo

应用私有目录文件读写(无需权限)

import fs from '@ohos.file.fs';

function writePrivateFile(context) {
  const filePath = context.filesDir + '/demo.txt';
  const file = fs.openSync(
    filePath,
    fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE
  );
  fs.writeSync(file.fd, 'Hello HarmonyOS');
  fs.closeSync(file);
}

这段代码在任何设备上都能直接跑。

适合用在:

  • 升级包缓存
  • 日志文件
  • 本地配置

访问公共媒体文件(需要权限)

import fs from '@ohos.file.fs';

function readPublicFile() {
  const uri = 'file://media/Photo/test.jpg';
  const file = fs.openSync(uri, fs.OpenMode.READ_ONLY);
  fs.closeSync(file);
}

如果你没申请权限,这里会直接失败。

实际应用场景分析

场景一:OTA 升级包管理

推荐方案:

  • 下载到应用私有目录
  • 不走公共存储
  • 不申请任何文件权限

示例代码:

function getUpgradePath(context) {
  return context.filesDir + '/upgrade/update.bin';
}

这样做的好处是:

  • 权限最少
  • 风险最低
  • 稳定性最高

场景二:用户手动导入文件

这种情况最推荐用文件选择器

import picker from '@ohos.file.picker';

async function selectFile() {
  const photoPicker = new picker.PhotoViewPicker();
  const result = await photoPicker.select();
  console.info('用户选择的文件:', JSON.stringify(result));
}

系统会自动处理权限弹窗,你只拿结果。

场景三:分布式设备间文件同步

思路很简单:

  1. 文件先放私有目录
  2. 用分布式能力同步
  3. 不直接访问对方文件系统

示例路径统一:

const syncDir = context.filesDir + '/distributed/';

这样可以保证:

  • 每台设备都有独立沙箱
  • 不破坏系统安全模型

QA 常见问题

Q1:为什么我申请了权限还是读不到文件?

通常原因有三种:

  1. URI 写错
  2. 权限申请时机不对
  3. 用户拒绝了授权

建议在代码里明确判断授权结果。

Q2:能不能一上来就申请所有权限?

不建议。

鸿蒙审核更看重最小权限原则,乱申请容易被打回。

Q3:文件路径能不能硬编码?

不建议。

不同设备、系统版本路径可能不一样,优先用 context.filesDir

总结

在 HarmonyOS 中,文件权限的核心可以总结为一句话:

能用私有目录就别碰公共目录
能让系统管权限就别自己折腾

只要你记住这几个原则:

  • 私有目录优先
  • 权限按需申请
  • 文件选择器优先
  • 拒绝场景必须兜底

文件权限这一块,基本就不会再踩大坑。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐