HarmonyOs应用《日记本》开发第14篇 - Preferences 轻量级数据存储

发布时间:2026/7/27 8:20:31
HarmonyOs应用《日记本》开发第14篇 - Preferences 轻量级数据存储
HarmonyOS 提供了多种数据存储方案其中 Preferences 是最轻量级的键值对存储方案适用于小量数据的持久化。日记项目使用 Preferences 作为唯一的数据存储方案本篇将深入解析 Preferences API 的使用方法和最佳实践。Preferences 概述什么是 PreferencesPreferences 是 HarmonyOS 提供的轻量级数据存储方案类似于 Android 的 SharedPreferences 或浏览器的 localStorage。它以键值对的形式存储数据数据会持久化到本地文件中。适用场景场景适合不适合用户设置✅-小量数据 数百条✅大量数据简单数据结构✅复杂关系型数据低频读写✅高频实时读写日记存储本项目✅-与其他存储方案对比方案数据量复杂度适用场景Preferences小KB级低配置、少量记录关系型数据库 (RDB)中MB级中结构化数据分布式数据服务 (DDS)中高多设备同步文件存储任意中大文件、媒体Preferences API 详解导入import{preferences}fromkit.ArkData;创建/获取 Preferences 实例asyncinit(context:Context):Promisevoid{try{this.storeawaitpreferences.getPreferences(context,{name:diary_store});}catch(e){console.error(DiaryStore init error: JSON.stringify(e));}}参数说明context应用上下文来自 UIAbilitynamePreferences 实例名称对应一个本地文件文件位置数据存储在应用沙箱目录下路径类似/data/storage/el2/database/{bundleName}/preferences/diary_store.xml写入数据 — putawaitthis.store.put(STORE_KEY,JSON.stringify(list));put 方法签名put(key:string,value:ValueType):Promisevoid支持的数据类型类型示例stringhellonumber42booleantrueArray[1, 2, 3]Uint8Arraynew Uint8Array([1, 2])日记项目的存储方式将整个日记数组序列化为 JSON 字符串存储constSTORE_KEYdiary_list;// 存储awaitthis.store.put(STORE_KEY,JSON.stringify(list));// list [{ id: ..., title: ..., content: ..., ... }, ...]读取数据 — getconstrawawaitthis.store.get(STORE_KEY,[])asstring;get 方法签名get(key:string,defValue:ValueType):PromiseValueType参数说明key要读取的键defValue默认值当键不存在时返回// 第一次使用应用时diary_list 不存在constrawawaitthis.store.get(STORE_KEY,[])asstring;// raw [] → 空数组字符串持久化 — flushawaitthis.store.flush();重要put方法只是将数据写入内存缓存必须调用flush才能将数据真正持久化到文件。// 完整的写入流程awaitthis.store.put(STORE_KEY,JSON.stringify(list));// 写入内存awaitthis.store.flush();// 持久化到文件如果忘记 flush数据在内存中存在当前会话可以读取应用关闭后数据丢失这是最常见的 Preferences 使用错误检查键是否存在 — hasconsthasKeyawaitthis.store.has(STORE_KEY);删除数据 — deleteawaitthis.store.delete(STORE_KEY);awaitthis.store.flush();清空所有数据 — clearawaitthis.store.clear();awaitthis.store.flush();日记项目的存储设计存储结构Preferences: diary_store └── diary_list (key) → JSON 字符串 (value) JSON 结构: [ { id: diary_1721856000000_42, title: 美好的一天, content: 今天去公园散步..., date: 2026-07-24, createTime: 1721856000000, updateTime: 1721856000000, mood: happy, weather: sunny }, { id: diary_1721855000000_15, title: 工作日记, content: 今天完成了项目..., date: 2026-07-23, ... } ]读写流程读取流程asyncgetAllDiaries():PromiseDiaryItem[]{if(!this.store){return[];}try{// 1. 读取 JSON 字符串constrawawaitthis.store.get(STORE_KEY,[])asstring;// 2. 反序列化为数组constlist:ArrayDiaryItemJSON.parse(raw);// 3. 按更新时间排序list.sort((a:DiaryItem,b:DiaryItem)b.updateTime-a.updateTime);returnlist;}catch(e){console.error(getAllDiaries error: JSON.stringify(e));return[];}}读取流程图 Preferences 文件 │ │ store.get(diary_list, []) ▼ JSON 字符串: [{id:diary_...,title:...,content:...,...}] │ │ JSON.parse() ▼ ArrayDiaryItem: [{ id: diary_..., title: ..., ... }] │ │ sort by updateTime ▼ 排序后的数组最近更新在前写入流程asyncsaveDiary(diary:DiaryItem):Promiseboolean{if(!this.store){returnfalse;}try{// 1. 读取现有列表constlistawaitthis.getAllDiaries();// 2. 查找并更新或新增constnowDate.now();letfoundfalse;for(leti0;ilist.length;i){if(list[i].iddiary.id){diary.updateTimenow;list[i]diary;// 更新foundtrue;break;}}if(!found){diary.createTimenow;diary.updateTimenow;if(!diary.id){diary.iddiary_now_Math.floor(Math.random()*1000);}list.push(diary);// 新增}// 3. 序列化并写入awaitthis.store.put(STORE_KEY,JSON.stringify(list));// 4. 持久化awaitthis.store.flush();returntrue;}catch(e){console.error(saveDiary error: JSON.stringify(e));returnfalse;}}删除流程asyncdeleteDiary(id:string):Promiseboolean{if(!this.store){returnfalse;}try{// 1. 读取现有列表constlistawaitthis.getAllDiaries();// 2. 过滤掉要删除的项constnewListlist.filter((item:DiaryItem)item.id!id);// 3. 序列化并写入awaitthis.store.put(STORE_KEY,JSON.stringify(newList));// 4. 持久化awaitthis.store.flush();returntrue;}catch(e){console.error(deleteDiary error: JSON.stringify(e));returnfalse;}}“读-改-写” 模式分析日记项目的存储操作采用经典的读-改-写模式读取全部 → 修改目标项 → 写入全部优点简单直观不需要额外的查询语句一致性整个列表一起操作不会有部分更新问题原子性flush 保证了数据的完整写入缺点全量读写每次操作都要读取和写入整个列表数据量限制不适合大量数据数千条以上并发问题多个异步操作可能产生竞态对日记场景的适用性对于日记应用用户通常只有几十到几百条日记每条日记数据量小几百字节写操作不频繁用户手动保存Preferences 完全满足需求数据监听Preferences 支持数据变化监听// 注册数据变化监听this.store.on(change,(key:string){if(keySTORE_KEY){console.info(日记数据已变化);// 可以触发 UI 刷新}});日记项目当前没有使用监听而是通过onPageShow手动刷新onPageShow():void{this.loadData();// 每次页面显示时重新加载数据}性能考量读写性能操作 耗时估算 ────────────────────────── get ~1ms put ~1ms flush ~5-10ms JSON.parse ~1ms100条日记 JSON.stringify ~1ms100条日记对于100条以内的日记每次操作的耗时在10ms以内用户无感知。数据量估算单条日记大小估算: id: ~30 bytes title: ~50 bytes content: ~200 bytes date: ~10 bytes timestamps: ~20 bytes mood: ~10 bytes weather: ~10 bytes JSON 开销: ~50 bytes ───────────────────── 总计: ~380 bytes 100条日记 ≈ 38KB 1000条日记 ≈ 380KB Preferences 建议不超过数MB日记应用完全在安全范围内。小结Preferences 是日记项目数据持久化的核心方案轻量高效键值对存储API 简单JSON 序列化将数组结构存储为字符串读-改-写模式适用于小量数据的 CRUDflush 持久化确保数据写入文件防御性编程空值检查和 try-catch 保证健壮性对于日记这样的轻量级应用Preferences 是最佳选择——简单、高效、可靠。