在这里插入图片描述
在这里插入图片描述

子玥酱 (掘金 / 知乎 / CSDN / 简书 同名)

大家好,我是 子玥酱,一名长期深耕在一线的前端程序媛 👩‍💻。曾就职于多家知名互联网大厂,目前在某国企负责前端软件研发相关工作,主要聚焦于业务型系统的工程化建设与长期维护。

我持续输出和沉淀前端领域的实战经验,日常关注并分享的技术方向包括 前端工程化、小程序、React / RN、Flutter、跨端方案
在复杂业务落地、组件抽象、性能优化以及多端协作方面积累了大量真实项目经验。

技术方向:前端 / 跨端 / 小程序 / 移动端工程化
内容平台:
掘金、知乎、CSDN、简书
创作特点:
实战导向、源码拆解、少空谈多落地
文章状态:
长期稳定更新,大量原创输出

我的内容主要围绕 前端技术实战、真实业务踩坑总结、框架与方案选型思考、行业趋势解读 展开。文章不会停留在“API 怎么用”,而是更关注为什么这么设计、在什么场景下容易踩坑、真实项目中如何取舍,希望能帮你在实际工作中少走弯路。

子玥酱 · 前端成长记录官 ✨
👋 如果你正在做前端,或准备长期走前端这条路
📚 关注我,第一时间获取前端行业趋势与实践总结
🎁 可领取 11 类前端进阶学习资源(工程化 / 框架 / 跨端 / 面试 / 架构)
💡 一起把技术学“明白”,也用“到位”

持续写作,持续进阶。
愿我们都能在代码和生活里,走得更稳一点 🌱

摘要

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

  • 下载 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开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐