核心思想概括
-
Android: 基于 Linux 文件系统 和 Scoped Storage (分区存储) 模型。应用对大部分外部存储的访问受到严格限制,强调应用数据隔离和用户隐私保护。 -
ArkTS (HarmonyOS): 基于 HarmonyOS 应用沙箱 和 统一的文件管理接口。它继承了类似的安全思想,但提供了更简洁、统一的 API ( @ohos.file.fs等),并且对“应用私有目录”和“公共目录”的访问有明确区分。
对比表格
|
|
|
|
|
|---|---|---|---|
| API 来源 |
Context, Environment, MediaStore)
|
@ohos.file.fs, @ohos.file.fileuri 等
|
|
| 沙箱/隔离模型 | Scoped Storage (分区存储) | 应用沙箱 |
|
| 1. 应用私有目录 |
|
|
这是两者最相似的部分
|
|
|
Context.getFilesDir() |
context.filesDir |
|
|
|
Context.getCacheDir() |
context.cacheDir |
|
|
|
Context.getExternalFilesDir() |
context.externalFilesDir |
|
|
|
Context.getExternalCacheDir() |
context.externalCacheDir |
|
| 2. 公共目录 |
|
|
这是差异最大的部分
|
|
|
MediaStoreMediaStore.Images.Media.EXTERNAL_CONTENT_URI |
@ohos.file.photoAccessHelper
@ohos.file.audioAccessHelper, @ohos.file.videoAccessHelper
|
Android
MediaStore ContentProvider 进行增删改查。HarmonyOS: 通过专门的 AccessHelper 模块操作,需要申请对应的 ohos.permission.READ_XXX_STORAGE / WRITE_XXX_STORAGE 权限。
|
|
|
MediaStore.Downloads
|
@ohos.file.fileurifileuri.getUriFromPath 获取 Download 目录的 URI 进行操作。
|
MediaStore。HarmonyOS 通过 fileuri 模块处理。
|
|
|
受限
/sdcard/DCIM)访问已基本不可行。
|
受限
|
|
| 3. 权限模型 |
|
|
|
|
|
无需权限 | 无需权限 |
|
|
|
READ_EXTERNAL_STORAGEWRITE_EXTERNAL_STORAGE |
细粒度媒体权限
- ohos.permission.READ_IMAGE_VIDEO- ohos.permission.WRITE_IMAGE_VIDEO- ohos.permission.READ_AUDIO- ohos.permission.WRITE_AUDIO
|
趋势一致
|
| 4. 数据库存储 |
|
|
|
|
|
|
|
|
|
|
|
@ohos.data.relationalStore |
|
代码示例对比
1. 写入应用私有文件
Android (Kotlin):
val filename = "myfile.txt"
val contents = "Hello, Android!"
context.openFileOutput(filename, Context.MODE_PRIVATE).use {
it.write(contents.toByteArray())
}
// 文件路径类似:/data/data/<package_name>/files/myfile.txt
ArkTS (HarmonyOS):
import fs from '@ohos.file.fs';
let context = ... // 获取UIAbility的Context
let filePath = context.filesDir + '/myfile.txt';
let file = fs.openSync(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
fs.writeSync(file.fd, 'Hello, HarmonyOS!');
fs.closeSync(file);
// 文件路径类似:/data/app/el2/100/base/<package_name>/files/myfile.txt
2. 保存一张图片到公共图库
Android (Kotlin):
// 1. 使用 MediaStore 插入一条记录,获取 Uri
val values = ContentValues().apply {
put(MediaStore.Images.Media.DISPLAY_NAME, "MyImage.jpg")
put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES)
}
val uri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
// 2. 通过 Uri 打开输出流并写入图片数据
uri?.let {
contentResolver.openOutputStream(it)?.use { stream ->
// bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream)
}
}
ArkTS (HarmonyOS):
// 1. 导入模块
import photoAccessHelper from '@ohos.file.photoAccessHelper';
import fs from '@ohos.file.fs';
// 2. 获取 PhotoAccessHelper 实例
let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
// 3. 创建图片资源创建选项
let options = {
title: 'MyImage.jpg'
};
// 4. 创建文件并获取 Uri
phAccessHelper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'MyImage.jpg', options).then(async (uri) => {
// 5. 通过 Uri 打开文件并进行写入操作
let file = await fs.open(uri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
// ... 将图片数据写入 file.fd
fs.closeSync(file);
}).catch((err) => {
console.error(`Failed to create asset. Code is ${err.code}, message is ${err.message}`);
});
总结与迁移建议
-
概念映射:将 Android 的 Context.getFilesDir()等概念直接映射到 ArkTS 的context.filesDir。私有目录的操作逻辑非常相似。 -
公共文件访问是重点:迁移时,需要将大量使用 MediaStore和File路径的代码,重构为使用 HarmonyOS 对应的AccessHelper(如photoAccessHelper)和fileuri模块。 -
权限调整:注意将 Android 的存储权限申请逻辑,改为 HarmonyOS 的细粒度媒体权限。 -
API 学习:HarmonyOS 的文件 API 设计更偏向于 Node.js/前端风格(如 openSync,writeSync),对于有后端或前端经验的开发者来说可能更容易上手。

