随着移动设备存储容量的不断增加,用户对存储空间的管理需求也日益增强。HarmonyOS 提供了丰富的接口和工具,帮助开发者更好地管理应用的存储空间。本文将结合实际代码示例,介绍如何在 HarmonyOS 应用中实现存储空间的查询、缓存清理以及文件管理功能。
场景一:计算应用缓存大小并进行清理
- 获取应用缓存大小 通过 storageStatistics.getCurrentBundleStats 接口,可以获取当前应用的存储空间大小(包括缓存文件、安装文件等)。
import storageStatistics from '@ohos.storageStatistics';
storageStatistics.getCurrentBundleStats((err: BusinessError, bundleStats: storageStatistics.BundleStats) => {
if (err) {
console.error(Invoke getCurrentBundleStats failed, code is ${err.code}, message is ${err.message});
} else {
console.info(Invoke getCurrentBundleStats succeeded, cacheSize is ${bundleStats.cacheSize});
}
});
- 清理缓存文件 缓存文件通常存储在以下路径:
/data/storage/el1/base/cache /data/storage/el1/base/haps/entry/cache /data/storage/el2/base/cache /data/storage/el2/base/haps/entry/cache 可以通过 Context.cacheDir 获取缓存路径,并递归删除缓存文件。
import fs from '@ohos.file.fs'; import contextConstant from '@ohos.app.ability.contextConstant';
let cacheDir: string[] = []; let moduleContext = this.context.createModuleContext('entry');
// 获取不同加密级别的缓存路径 cacheDir.push(moduleContext.cacheDir); cacheDir.push(this.context.cacheDir); moduleContext.area = contextConstant.AreaMode.EL1; this.context.area = contextConstant.AreaMode.EL1; cacheDir.push(moduleContext.cacheDir); cacheDir.push(this.context.cacheDir);
for (let i = 0; i < cacheDir.length; i++) { let cache = cacheDir[i]; let exist = fs.accessSync(cache); if (exist) { try { fs.rmdirSync(cache); } catch (err) { console.log(err); } } }
HarmonyOS开发之原生应用占用空间管理与优化_HarmonyOS Next
场景二:对文件夹中的图片进行展示并选择性清理
- 制定图片过滤规则 通过 fs.listFileSync 方法列出指定目录下的图片文件,并根据后缀名过滤出目标文件。
let listFileOption: ListFileOptions = { recursion: true, listNum: 0, filter: { suffix: ['.jpg', '.png'], }, };
let fileNames = fs.listFileSync(dirPath, listFileOption); let imagePaths: string[] = [];
for (let i = 0; i < fileNames.length; i++) { let filePath = dirPath + fileNames[i]; console.log(filePath); imagePaths.push(filePath); }
- 将图片转换为 PixelMap 使用 image.createImageSource 和 createPixelMapSync 方法,将图片文件转换为 PixelMap 对象,以便后续展示。
function Picture(mediaPath: string): image.PixelMap { let options: image.SourceOptions = { sourceSize: { width: 100, height: 100 }, sourceDensity: 0, }; let decodingOptions: image.DecodingOptions = {};
let file = fs.openSync(mediaPath, fs.OpenMode.READ_ONLY); let imageSource = image.createImageSource(file.fd, options); let imageInfo = imageSource.getImageInfoSync();
// 裁剪图片为正方形 if (imageInfo.size.height > imageInfo.size.width) { let a = (imageInfo.size.height - imageInfo.size.width) / 2; decodingOptions.desiredRegion = { size: { width: imageInfo.size.width, height: imageInfo.size.width }, x: 0, y: a, }; } else { let a = (imageInfo.size.width - imageInfo.size.height) / 2; decodingOptions.desiredRegion = { size: { width: imageInfo.size.height, height: imageInfo.size.height }, x: a, y: 0, }; }
return imageSource.createPixelMapSync(decodingOptions); }
- 展示图片并支持删除 使用 Grid 组件展示图片,并通过长按手势触发删除操作。
@Builder MenuBuilder(path: string) { Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) { Text('删除') .fontSize(20) .width(100) .height(50) .textAlign(TextAlign.Center) .onClick(() => { try { fs.unlinkSync(path); let i = this.mediaPath.indexOf(path); this.mediaPath.splice(i, 1); } catch (err) { console.log(err); } }); }.width(100); }
Grid() { ForEach(this.mediaPath, (item: string) => { GridItem() { Image(Picture(item)) .bindContextMenu(this.MenuBuilder(item), ResponseType.LongPress) .objectFit(ImageFit.Fill) .autoResize(false); }; }); }
- 一键删除所有图片 通过弹窗确认后,批量删除所有图片文件。
Button('一键删除') .onClick(() => { let uiContext = this.getUIContext(); let promptAction = uiContext.getPromptAction(); let contentNode = new ComponentContent(uiContext, wrapBuilder(BuildText), this.mediaPath); this.content = contentNode;
try {
promptAction.openCustomDialog(contentNode, {
showInSubWindow: false,
offset: { dx: 5, dy: 5 },
onWillDisappear: () => {
this.mediaPath = FindAll(getContext().filesDir);
},
});
} catch (error) {
console.error(`OpenCustomDialog args error code is ${(error as BusinessError).code}, message is ${(error as BusinessError).message}`);
}
});
常见问题解答 Q1: 为什么通过 statvfs.getTotalSizeSync 查询到的设备总空间与设置中显示的不一致? A: statvfs.getTotalSizeSync 获取的是 data 分区大小,三方应用仅能查询到自己能够使用的空间大小,暂无查询手机总内存大小的接口。
Q2: 是否可以查询外卡空间大小? A: 暂不支持。
Q3: 为什么有些中文文件名的文件搜不到? A: 当前 HarmonyOS 文件系统仅支持 UTF-8 格式,GBK 格式的中文文件名可能会导致乱码。
Q4: 为什么删除文件夹会报错 Directory not empty? A: fs.rmdir 是递归删除,但当子目录中存在高权限文件时,接口无法删除这些文件,从而导致报错。 文章来源:ximaonetwork.cn