当前位置: 首页 > news >正文

探秘鸿蒙 HarmonyOS NEXT:鸿蒙存储核心技术全解析

引言

本文章基于HarmonyOS NEXT操作系统,API12以上的版本。

ArkTS (ArkUI 框架) 中,用户首选项 (Preferences)持久化存储 (PersistentStorage) 都用于数据存储,但它们有不同的应用场景和特点。


1. 用户首选项 (Preferences)

概念

  • 轻量级键值对存储,主要用于存储用户设置或小型数据,如应用配置、主题模式、语言等。
  • 适用于 频繁读取少量更新 的数据存储。

特点

  • 主要用于存储简单的键值对,如 booleanstringnumber 等。
  • 数据存储在 本地沙盒 中,并会在 应用重新启动后保持不变
  • 适合存储 小量数据,如 UI 设置、开关状态等。

使用场景

  • 主题模式(浅色/深色模式)。
  • 语言偏好设置(中文/英文)。
  • 记住用户是否已登录(布尔值)。
  • 开关设置,如通知开关。

示例代码

import preferences from '@ohos.data.preferences';

// 获取 Preferences 实例
async function saveThemePreference(isDarkMode: boolean) {
    const preferencesInstance = await preferences.getPreferences(globalThis, 'user_settings');
    await preferencesInstance.put('dark_mode', isDarkMode);
    await preferencesInstance.flush(); // 确保数据写入
}

// 读取 Preferences
async function getThemePreference(): Promise<boolean> {
    const preferencesInstance = await preferences.getPreferences(globalThis, 'user_settings');
    return await preferencesInstance.get('dark_mode', false); // 默认值 false
}

2. 核心API介绍

Preferences 组件主要提供 读取、写入、删除 用户首选项的方法。常用的 API 主要包括:

(1)获取 Preferences 实例

在 OpenHarmony 设备上,用户首选项存储在 文件 中,因此需要指定存储路径。

import preferences from '@ohos.data.preferences';

async function getPreferences() {
    try {
        const pref = await preferences.getPreferences(globalThis.getContext(), 'settings.preferences');
        return pref;
    } catch (err) {
        console.error('获取 Preferences 失败:', err);
    }
}
  • getPreferences(context, fileName): 通过 文件名 获取 Preferences 实例,该文件存储在应用的数据目录下。
  • context: 需要传入全局应用上下文 globalThis.getContext()

(2)存储数据

使用 put() 方法存储键值对数据,并使用 flush() 进行同步保存。

async function savePreferences() {
    const pref = await getPreferences();
    if (!pref) return;

    pref.put('theme', 'dark');  // 存储字符串
    pref.put('volume', 50);      // 存储数值
    pref.put('notifications', true);  // 存储布尔值

    await pref.flush();  // 立即保存到本地
    console.log('数据已保存');
}
  • put(key, value): 存储 key-value 键值对。
  • flush(): 同步 写入存储,否则数据可能不会立即写入。

(3)读取数据

使用 get() 方法获取存储的数据:

async function loadPreferences() {
    const pref = await getPreferences();
    if (!pref) return;

    const theme = pref.get('theme', 'light');  // 默认值 "light"
    const volume = pref.get('volume', 10);     // 默认值 10
    const notifications = pref.get('notifications', false);  // 默认值 false

    console.log(`当前主题: ${theme}, 音量: ${volume}, 通知开关: ${notifications}`);
}
  • get(key, defaultValue): 读取 存储的值,如果键不存在,则返回默认值。

(4)删除数据

使用 delete() 方法移除指定键:

async function removePreferenceKey() {
    const pref = await getPreferences();
    if (!pref) return;

    pref.delete('theme');  // 删除 "theme" 配置项
    await pref.flush();  // 确保数据同步更新
    console.log('主题设置已删除');
}
  • delete(key): 删除指定 key 对应的值。

(5)清除所有数据

可以使用 clear() 方法清空整个 Preferences。

async function clearPreferences() {
    const pref = await getPreferences();
    if (!pref) return;

    pref.clear();  // 清空所有数据
    await pref.flush();
    console.log('所有用户设置已清除');
}
  • clear(): 清空所有存储的键值对数据。

3. 持久化存储 (PersistentStorage)

概念

  • 更通用的数据存储方式,可以用于存储更大规模的结构化数据,如对象、列表或复杂数据。
  • 通常与本地数据库(如 SQLite文件存储)结合使用。

特点

  • 适用于 存储较大数据量,如缓存数据、用户数据、应用状态等。
  • 提供更丰富的 API,支持复杂的数据管理。
  • 数据存储在应用的私有目录,可以长期存储,即使应用重启也不会丢失。

使用场景

  • 用户账户信息(如用户名、头像)。
  • 应用的缓存数据(如搜索历史、下载列表)。
  • 复杂的设置数据(如 JSON 结构的配置)。
  • 离线数据存储(如离线文档、任务列表)。

示例代码(基于数据存储组件)

import { PersistentStorage } from '@ohos.data.storage';

// 保存数据
async function saveUserData(userData: any) {
    const storage = new PersistentStorage('user_data'); // 创建存储实例
    await storage.set('profile', JSON.stringify(userData));
    await storage.flush(); // 确保数据写入
}

// 读取数据
async function getUserData(): Promise<any> {
    const storage = new PersistentStorage('user_data');
    const userDataStr = await storage.get('profile', '{}'); // 默认值为空对象
    return JSON.parse(userDataStr);
}

4. 核心API介绍

(1)存储数据

使用 set() 方法存储数据:

storage.set('username', 'Alice');
storage.set('age', 25);
storage.set('isPremiumUser', true);
  • 该方法支持存储 字符串、数值、布尔值等基本数据类型
  • 数据存储在应用本地,不会在应用重启时丢失。

(2)获取数据

使用 get<T>() 方法获取存储的数据:

let username: string = storage.get<string>('username', 'defaultUser');
let age: number = storage.get<number>('age', 0);
let isPremium: boolean = storage.get<boolean>('isPremiumUser', false);
  • 参数
    • 第一个参数是键(key)。
    • 第二个参数是 默认值(当 key 不存在时返回此值)。
  • 返回值类型 需要显式指定(泛型 <T>)。

(3)删除数据

使用 delete() 方法删除某个键值:

storage.delete('username');
  • 删除后,使用 get() 方法查询时将返回默认值。

(4)清空所有数据

使用 clear() 方法删除所有存储的键值对:

storage.clear();
  • 该方法会清除 PersistentStorage 中存储的所有数据,谨慎使用!

(5)数据是否存在

使用 has() 方法检查某个键是否存在:

if (storage.has('username')) {
    console.log('用户名已存储');
} else {
    console.log('用户名不存在');
}

(6)简单封装

以下是一个简单封装的 PersistentStorage 工具类:

import { PersistentStorage } from '@ohos.data.preferences';

class StorageUtil {
    private static instance: PersistentStorage;

    private constructor() {}

    /**
     * 获取 PersistentStorage 实例(单例模式)
     */
    private static getInstance(): PersistentStorage {
        if (!this.instance) {
            this.instance = PersistentStorage.getSharedInstance();
        }
        return this.instance;
    }

    /**
     * 存储数据
     * @param key 键名
     * @param value 要存储的值(支持 string、number、boolean)
     */
    static set<T>(key: string, value: T): void {
        this.getInstance().set(key, value);
    }

    /**
     * 获取存储数据
     * @param key 键名
     * @param defaultValue 默认值(如果 key 不存在,则返回此值)
     * @returns 存储的数据
     */
    static get<T>(key: string, defaultValue: T): T {
        return this.getInstance().get<T>(key, defaultValue);
    }

    /**
     * 删除指定 key 的存储数据
     * @param key 键名
     */
    static delete(key: string): void {
        this.getInstance().delete(key);
    }

    /**
     * 清除所有存储数据
     */
    static clear(): void {
        this.getInstance().clear();
    }

    /**
     * 判断某个 key 是否存在
     * @param key 键名
     * @returns 存在返回 true,否则返回 false
     */
    static has(key: string): boolean {
        return this.getInstance().has(key);
    }
}

export default StorageUtil;

// 示例使用
StorageUtil.set('username', 'Alice');
const username = StorageUtil.get('username', 'defaultUser');
console.log(`Username: ${username}`);
StorageUtil.delete('username');
console.log(StorageUtil.has('username')); // false
StorageUtil.clear();

5. 对比总结

特性用户首选项 (Preferences)持久化存储 (PersistentStorage)
存储方式轻量级键值对存储适用于存储复杂数据
数据类型string, boolean, number复杂数据结构(JSON、列表等)
数据量小量数据大量数据
适用场景主题、语言、用户偏好用户信息、缓存、离线数据
读写性能读取速度快适用于批量存储
数据持久性持久化存储持久化存储

6. 使用建议

  • 如果只是存储 简单的设置数据,比如开关状态、主题模式,建议使用 Preferences
  • 如果需要存储 复杂对象(如 JSON 数据)或者 大量数据(如历史记录、缓存),建议使用 PersistentStorage

当然如果你的数据规模较大,还可以考虑 数据库 (键值型数据库KVManager或者关系型数据库RdbStore) 进行存储,以提高查询和管理效率。

相关文章:

  • SLAM十四讲【四】相机与图像
  • MySQL 字符集
  • 华为昇腾AscendCL推理引擎入门
  • epoll原理以及系统调用案例分析
  • 动态规划——完全背包问题
  • 【中文翻译】第8章-The Algorithmic Foundations of Differential Privacy
  • [spring] Spring JPA - Hibernate 多表联查 3
  • 人形机器人科普
  • Unity Shader 的编程流程和结构
  • 现代前端质量保障与效能提升实战指南
  • Noteexpress插入参考文献无法对齐
  • Linux生产者消费者模型
  • 快速求出质数
  • 【算法训练】单向链表
  • pandas中新增的case_when()方法
  • c++ 命名空间 namespace
  • 【 <二> 丹方改良:Spring 时代的 JavaWeb】之 Spring Boot 中的数据验证:使用 Hibernate Validator
  • 数据建模流程: 概念模型>>逻辑模型>>物理模型
  • NSSCTF(MISC)——[NSSRound#4 SWPU]Type Message
  • 网络爬虫-2:基础与理论
  • 体坛联播|欧冠巴萨3比3战平国米,柯洁未进入国家集训队
  • 澎湃回声丨23岁小伙“被精神病8年”续:今日将被移出“重精”管理系统
  • 美参议院通过新任美国驻华大使任命,外交部回应
  • 马上评|什么才是地方文旅宣传的正确姿势
  • 广东省副省长刘红兵跨省调任湖南省委常委、宣传部长
  • 韩国下届大选执政党初选4进2结果揭晓,金文洙、韩东勋胜出