适配仓库: https://atomgit.com/oh-flutter/disk_space_2

适配分支: feat/ohos_disk_space_2_1.0.13

一、最终效果与适配目标

下载离线包、解压资源、缓存视频之前,应用通常要先判断目标文件系统还有多少空间。disk_space_2 1.0.13 提供总容量、可用容量和指定目录可用容量三个常用接口,但原版没有鸿蒙平台注册,Flutter 在 OHOS 上调用会找不到原生实现。

这次我没有改动 DiskSpace.getFreeDiskSpacegetTotalDiskSpacegetFreeDiskSpaceForPath() 的返回类型,而是把鸿蒙 statvfs 返回的字节换算为原库约定的 MiB。重点不是“能得到一个数字”,而是把查询对象、单位、路径限制和失败行为说清楚,避免业务拿错分区或把错误伪装成 0。

在这里插入图片描述

图 1:真机联合宿主显示总量、空闲量与指定目录结果。

验证点实测结果证据
总容量与可用容量103460 MiB / 67477.16015625 MiB图 1、图 6
指定沙箱目录查询成功,与默认目录位于同一文件系统图 6
不存在目录返回明确错误,不回退到默认路径图 6
自动化与构建13 项 Dart/Widget 测试、静态分析和 HAP 构建通过图 4、图 5

成果速览

项目内容
上游基线TAG v1.0.13,提交 472b7ca23bf714182a6c636f8e2533ad0bb7a5d6,MIT
适配分支feat/ohos_disk_space_2_1.0.13
适配 TAG尚未发布
真机受测提交0cb25f91bdda96fddbdfd465ea189678e2cf959b
当前分支 HEADbc1a4ba71c11acf4f80235de3f2e9df1e1002953,后续为文档提交
返回语义目标路径所在文件系统,单位 MiB
真机边界单机单次容量样本,不代表固定硬件规格

二、环境记录

项目实测值
Flutter OH3.41.10-ohos-1.0.1
Dart3.11.5
DevEco Studio26.0.0 Release
HarmonyOS SDKAPI 26,兼容 API 18
真机CHZ-AL00,HarmonyOS 7.0.0.105
插件disk_space_2 1.0.13

环境搭建沿用 Flutter OH 指南,本文只展开插件代码和验证。截至 2026 年 9 月 12 日,版本号最大的标签是预览版 3.44.9+ohos-0.0.1-canary1,最新正式稳定标签仍是本文实测的 3.41.10-ohos-1.0.1

三、仓库来源与分支

适配基线是上游标签 v1.0.13、提交 472b7ca23bf714182a6c636f8e2533ad0bb7a5d6。适配前逐项检查清单与目标组织仓库,在 2026 年 9 月 9 日的搜索范围内没有同名 OHOS 交付。AtomGit 仓库保留 MIT 许可证和原提交历史。

git clone https://atomgit.com/oh-flutter/disk_space_2.git
cd disk_space_2
git switch feat/ohos_disk_space_2_1.0.13
git branch --show-current

从基线复现分支和骨架的命令如下:

git switch -c feat/ohos_disk_space_2_1.0.13 472b7ca23bf714182a6c636f8e2533ad0bb7a5d6
flutter create --template=plugin --platforms=ohos --no-pub .

生成模板后,还要把通道改回原项目的 disk_space_2,并补路径校验、单位换算、异常映射和示例测试。图 2 汇总了实际 AtomGit origin、适配分支和 HEAD,可核对仓库来源与当前分支状态。

在这里插入图片描述

图 2:AtomGit 来源、适配分支和 HEAD 实时核验。

四、原接口真正要求什么

原 Dart API 返回 double?,单位是 MiB,而不是 bytes 或十进制 MB:

final totalMiB = await DiskSpace.getTotalDiskSpace;
final freeMiB = await DiskSpace.getFreeDiskSpace;
final cacheFreeMiB =
    await DiskSpace.getFreeDiskSpaceForPath(cacheDirectory.path);

默认查询应该落在应用数据目录所在的文件系统,不能为了数字看起来更大去查根目录或只读系统分区。指定路径则必须是应用能访问的本地目录。文档 URI、其他应用私有目录、普通文件和不存在的目录都不该悄悄回退到默认路径。

五、OHOS 实现与单位处理

pubspec.yaml 增加 DiskSpace2Plugin 后,ArkTS 在 onAttachedToEngine 保存应用 filesDir,并注册原通道。默认容量通过 @ohos.file.statvfs 获取:

const bytes = call.method === 'getFreeDiskSpace'
  ? await statfs.getFreeSize(this.filesDir)
  : await statfs.getTotalSize(this.filesDir);
result.success(bytes / 1048576);

这里除以 1,048,576,所以结果单位是 MiB;显示 GiB 时还要再除以 1024。原生接口可能返回超过 32 位的整数,Dart 端因此按 num 接收后转成 double,不能强制 cast 成 32 位整数。

指定目录接口先检查参数是绝对路径、不含 NUL,再用 fs.stat() 确认它确实是目录,最后查询该路径所在文件系统:

if (typeof path !== 'string' || !path.startsWith('/') || path.includes('\u0000')) {
  result.error('invalid_path', 'path must be an absolute local directory path, not a URI.', null);
  return;
}
const info = await fs.stat(path);
if (!info.isDirectory()) {
  result.error('invalid_path', 'path must refer to a directory.', null);
  return;
}

系统返回不存在、无权限等错误时映射为 path_unavailable,其他查询失败为 disk_space_error。满盘时 0 是合法空闲容量,不能当成异常;负数或非有限值才拒绝。

在这里插入图片描述

图 3:应用 filesDir、statvfs 查询与路径参数校验。

六、文档和示例交付

本分支保留原 README.mdCHANGELOG.md、MIT LICENSE 和其他平台源码,新增双语 OpenHarmony 文档、ohos/ HAR、完整 example/ohos/、Dart 测试、widget 测试和设备测试入口。仓库没有无意义地提交 HAP、依赖目录、签名配置或本机路径。

示例页面同时展示总量、空闲量、指定沙箱目录和错误状态。错误后可以重新查询,便于确认异常没有把页面卡死。

七、测试与构建

flutter pub get
flutter analyze
flutter test
cd example
flutter test
flutter build hap --debug --no-codesign

根目录 11 项测试和示例 2 项 widget 测试通过,共 13 项。它们覆盖整数到 double 的转换、MiB 单位、null、路径预检、异常传播以及页面恢复。静态分析无问题,无签名 HAP 构建成功。

隔离宿主随后从 AtomGit 分支解析固定提交 0cb25f91bdda96fddbdfd465ea189678e2cf959b,签名构建、安装和真实调用通过。后续文档 HEAD bc1a4ba 不应写成受测代码提交。

在这里插入图片描述

图 4:Flutter 检查复跑与 13 项 Dart/Widget 用例统计。

在这里插入图片描述

图 5:HAP 元数据、SHA-256 与远程依赖提交。

八、真机数据怎么解释

真机一次采样结果为:可用 67477.16015625 MiB,总量 103460 MiB;应用沙箱缓存目录查询也返回 67477.16015625 MiB,不存在目录被正确拒绝,未知方法返回 notImplemented

默认目录与缓存目录位于同一文件系统,所以两次可用容量相同是合理的,但这个数会随着设备写入变化,不能硬编码进测试。它也不表示“整台手机所有物理介质的容量”,而是目标路径所在文件系统的统计值。

Demo 通过 AtomGit 接入:

dependencies:
  disk_space_2:
    git:
      url: https://atomgit.com/oh-flutter/disk_space_2.git
      ref: 0cb25f91bdda96fddbdfd465ea189678e2cf959b

执行 flutter pub get 后,应在 pubspec.lock 中确认 resolved-ref 等于上述真机受测 SHA,而不是只确认依赖下载成功。

仓库自身的 integration 和 Hypium 套件没有执行;本文采用的是隔离宿主真机证据,二者不能混写。

在这里插入图片描述

图 6:真机容量、沙箱目录与非法路径的实测记录。

九、推送结果

git status --short
git add pubspec.yaml ohos example test README.OpenHarmony.md README.OpenHarmony_CN.md
git commit -m "feat: add OHOS support for disk_space_2"
git push -u origin feat/ohos_disk_space_2_1.0.13

远端仓库已公开,默认分支为适配分支;2026 年 9 月 12 日匿名核对的 HEAD 是 bc1a4ba71c11acf4f80235de3f2e9df1e1002953

十、FAQ

Q1:返回值为什么不是 bytes

  • 现象: 真机结果是带小数的几万,而不是大整数。
  • 原因: 原库公开 API 约定单位为 MiB。
  • 解决方法: OHOS 在原生层用 bytes 除以 1048576,业务显示 GiB 时再除以 1024。
  • 验证结果: Dart 测试和真机样本均符合该口径。

Q2:指定目录查询报 path_unavailable

  • 现象: 外部路径或不存在路径查询失败。
  • 原因: 路径不存在,或被应用沙箱拒绝访问。
  • 解决方法: 使用应用 files、cache、临时目录等真实可访问的绝对目录,不要传文档 URI。
  • 验证结果: 真机沙箱缓存目录成功,不存在目录按预期失败。

Q3:能否把容量结果当成固定设备规格

  • 现象: 多次查询有轻微变化。
  • 原因: 后台写入和缓存会改变文件系统可用空间。
  • 解决方法: 只判断范围或阈值,不断言固定值。
  • 验证结果: 当前文章只记录一次观测值,没有包装成恒定结论。

十一、总结

disk_space_2 现在可以在 Flutter 鸿蒙应用中查询默认数据文件系统的总量、空闲量和指定目录空闲量。实现保留原 MiB 返回语义,对路径和异常做了明确区分;13 项自动化、HAP 构建和 API 26 真机容量查询均已有证据。它解决的是文件系统空间判断,不是全盘资产统计,这个边界在业务接入时要继续保留。

十二、参考链接

欢迎加入CPF-Flutter 鸿蒙社区:https://atomgit.com/CPF-Flutter

Logo

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

更多推荐