沙盒文件的具体描述请参考添加链接描述
核心存储路径
// 获取基础目录上下文
let context = getContext(this) as common.UIAbilityContext
- 应用私有目录(无需权限)
// 缓存文件(系统可清理)
context.cacheDir + ‘/image_cache/xxx.jpg’
// 持久文件(卸载保留)
context.filesDir + ‘/user_data/config.json’
- 公共目录(需权限)
// 图片
mediaLibrary.MediaType.IMAGE => ‘Pictures/AppName/’
// 音频
mediaLibrary.MediaType.AUDIO => ‘Music/AppName/’
// 下载文件
ohos.file.environment.DIR_DOWNLOAD + ‘/AppName/’
下载文件存储示例
- 保存网络图片到缓存
async function cacheWebImage(url: string) {
const md5Name = util.generateHash(url) // 生成唯一文件名
const cachePath = `${context.cacheDir}/image_cache/${md5Name}.jpg`
// 下载并保存
const response = await http.get(url)
fs.writeFileSync(cachePath, response.result)
}
- 保存用户生成内容
// 保存用户编辑的笔记
function saveUserNote(content: string) {
const notePath = `${context.filesDir}/user_notes/${Date.now()}.txt`
// 创建目录(如果不存在)
if (!fs.accessSync(notePath)) {
fs.mkdirSync(`${context.filesDir}/user_notes`)
}
fs.writeFileSync(notePath, content)
}
- 保存到公共相册
async function saveToGallery(pixelMap: image.PixelMap) {
// 检查权限
if (!await checkMediaPermission()) return
// 创建媒体资源
const mediaLib = mediaLibrary.getMediaLibrary(context)
const file = await mediaLib.createAsset(
mediaLibrary.MediaType.IMAGE,
'my_photo.jpg',
mediaLibrary.DirectoryDir.DIR_PICTURES
)
// 写入数据
const fd = await file.open('w')
await imagePacker.encoding(pixelMap, fd)
await fd.close()
}
AI生成的并没有贴合最新的保存策略,通过MediaAssetRequest应该是正确的处理方法
async saveImageToGallery(pixelMap: image.PixelMap) {
// 1. 权限检查
const granted = await NZPermissionUtils.request(['ohos.permission.WRITE_MEDIA'])
if (granted) { // 权限已授予
try {
let context = getContext();
let fileUri = await this.saveImageByPixelMapToPath(pixelMap,"photo_"+Date.now(),context)
let helper = photoAccessHelper.getPhotoAccessHelper(getContext(this));
let assetChangeRequest: photoAccessHelper.MediaAssetChangeRequest = photoAccessHelper.MediaAssetChangeRequest.createImageAssetRequest(context, fileUri);
await helper.applyChanges(assetChangeRequest);
console.info('createAsset successfully, uri: ' + assetChangeRequest.getAsset().uri);
return true;
} catch (err) {
console.error(`create asset failed with error: ${err.code}, ${err.message}`);
return false;
}
} else {
return false;
}
}
这个做法先在cache中保存图片,然后通过assetRequest和fileUri一起生成媒体库图片
安全实践
- 路径防护
// 过滤非法字符
function safeFileName(name: string) {
return name.replace(/[^a-z0-9_\-]/gi, '_')
}
- 存储监控
// 检查剩余空间
const stat = fs.statSync(context.cacheDir)
if (stat.availableSize < 100 * 1024) { // 小于100KB时清理
cleanOldCache()
}
- 权限管理
// 动态请求媒体库权限
async function checkMediaPermission() {
const permissions: Array<string> = ['ohos.permission.READ_MEDIA', 'ohos.permission.WRITE_MEDIA']
return await abilityAccessCtrl.requestPermissionsFromUser(context, permissions)
}
路径对照表
|
目录类型 | 获取方法 | 典型用途 | 是否需要权限 |
---|---|---|---|
应用缓存目录 | context.cacheDir | 临时文件/网络缓存 | 否 |
应用文件目录 | context.filesDir | 用户配置/持久化数据 | 否 |
系统图片目录 | DIR_PICTURES | 用户生成的图片 | 是 |
系统下载目录 | DIR_DOWNLOAD | 用户下载的文件 | 是 |
应用专属外部存储 | context.externalCacheDir | 大体积临时文件 | 否 |
优化建议:
对用户敏感文件使用context.encryptDir加密存储
定期调用context.clearCache()清理过期缓存
使用fs.copyFileSync()替代直接写入关键文件防止写入中断损坏数据