轻量级数据存储概述
轻量级数据存储适用于对Key-Value结构的数据进行存取和持久化操作。应用获取某个轻量级存储对象后,该存储对象中的数据将会被缓存在内存中,以便应用获得更快的数据存取速度。应用也可以将缓存的数据再次写回文本文件中进行持久化存储,由于文件读写将产生不可避免的系统资源开销,建议应用减少对持久化文件的读写频率。
基本概念
- Key-Value数据结构 一种键值结构数据类型。Key是不重复的关键字,Value是数据值。
- 非关系型数据库 区别于关系数据库,不保证遵循ACID(Atomic、Consistency、Isolation及Durability)特性,不采用关系模型来组织数据,数据之间无关系。
运作机制
- 应用通过指定Preferences文件将其中的数据加载到Preferences实例,系统会通过静态容器将该实例存储在内存中,同一应用或进程中每个文件仅存在一个Preferences实例,直到应用主动从内存中移除该实例或者删除该Preferences文件。
- 应用获取到Preferences文件对应的实例后,可以从Preferences实例中读取数据,或者将数据存入Preferences实例中。通过调用flush或者flushSync方法可以将Preferences实例中的数据回写到文件里。
图1 轻量级数据存储运作机制
约束与限制
- 因Preferences实例会加载到内存中,建议存储的数据不超过一万条,并及时清理不再使用的实例,以便减少非内存开销。
- 数据中的key为string类型,要求非空且字符长度不超过80个。
- 当数据中的value为string类型时,允许为空,字符长度不超过8192个。
- 当value值为字符串型Set集合类型时,要求集合元素非空且字符长度不超过8192个。
轻量级数据存储开发
场景介绍
轻量级数据存储功能通常用于保存应用的一些常用配置信息,并不适合需要存储大量数据和频繁改变数据的场景。应用的数据保存在文件中,这些文件可以持久化地存储在设备上。需要注意的是,应用访问的实例包含文件所有数据,这些数据会一直加载在设备的内存中,直到应用主动从内存中将其移除前,应用可以通过Preferences的API进行数据操作。
接口说明
轻量级存储为应用提供key-value键值型的文件数据处理能力,支持应用对数据进行轻量级存储及查询。数据存储形式为键值对,键的类型为字符串型,值的存储数据类型包括整型、字符串型、布尔型、浮点型、长整型、字符串型Set集合。
创建存储实例
读取指定文件,将数据加载到Preferences实例,即可创建一个存储实例,用于数据操作。
类名 | 接口名 | 描述 |
---|---|---|
DatabaseHelper | DatabaseHelper(Context context) | DatabaseHelper是数据操作的辅助类。 |
DatabaseHelper | Preferences getPreferences(String name) | 获取数据存储文件对应的Preferences单实例,用于数据操作。数据文件存放在由上下文指定的目录里,该路径会因指定不同的上下文存在差异。 |
存入数据
通过Put系列方法,可以增加或修改Preferences实例中的数据。
类名 | 接口名 | 描述 |
---|---|---|
Preferences | Preferences putInt(String key, int value) | 设置Preferences实例中键对应的int类型的值。 |
Preferences | Preferences putString(String key, String value) | 设置Preferences实例中键对应的String类型的值。 |
读取数据
通过调用Get系列方法,可以读取Preferences中的数据。
类名 | 接口名 | 描述 |
---|---|---|
Preferences | int getInt(String key, int defValue) | 获取键对应的int类型的值。 |
Preferences | float getFloat(String key, float defValue) | 获取键对应的float类型的值。 |
数据持久化
通过执行flush方法,应用可以将缓存的数据再次写回文本文件中进行持久化存储。
类名 | 接口名 | 描述 |
---|---|---|
Preferences | void flush() | 将Preferences实例异步写入文件。 |
Preferences | boolean flushSync() | 将Preferences实例同步写入文件。 |
订阅数据变化
订阅数据变化需要指定PreferencesObserver作为回调方法。订阅的key的值发生变更后,当执行flush方法时,PreferencesObserver被回调。
类名 | 接口名 | 描述 |
---|---|---|
Preferences | void registerObserver(PreferencesObserver preferencesObserver) | 订阅数据变化。 |
Preferences | void unRegisterObserver(PreferencesObserver preferencesObserver) | 注销订阅。 |
Preferences.PreferencesObserver | void onChange(Preferences preferences, String key) | 订阅者的回调方法,数据变化会触发回调该方法。 |
删除数据文件
通过调用以下两种接口,可以删除数据实例或对应的文件。
类名 | 接口名 | 描述 |
---|---|---|
DatabaseHelper | boolean deletePreferences(String name) | 将Preferences实例从内存中移除,同时删除其在设备上的持久化文件。 |
DatabaseHelper | void removePreferencesFromCache(String name) | 仅将Preferences实例从内存中移除。 |
移动数据文件
类名 | 接口名 | 描述 |
---|---|---|
DatabaseHelper | boolean movePreferences(Context sourceContext, String sourceName, String targetName) | 移动数据持久化文件。 |
开发步骤
获取Preferences实例。
读取指定文件,将数据加载到Preferences实例,用于数据操作。
代码语言:javascript复制Context context = getContext(); // 数据文件存储路径:/data/data/{PackageName}/{AbilityName}/preferences。
// Context context = getApplicationContext(); // 数据文件存储路径:/data/data/{PackageName}/preferences。
DatabaseHelper databaseHelper = new DatabaseHelper(context); // context入参类型为ohos.app.Context。
String fileName = "test_pref"; // fileName表示文件名,其取值不能为空,也不能包含路径,默认存储目录可以通过context.getPreferencesDir()获取。
Preferences preferences = databaseHelper.getPreferences(fileName);
读取数据。
使用Preferences get方法读取数据。
代码语言:javascript复制preferences.putInt("intKey", 3);
preferences.putString("StringKey", "String value");
数据持久化。
应用存入数据到Preferences实例后,可以通过flush或者flushSync方法将Preferences实例回写到文件中。
代码语言:javascript复制preferences.flush(); // 异步方法
代码语言:javascript复制bool result = preferences.flushSync(); // 同步方法
订阅数据变化。
应用订阅数据变化需要指定PreferencesObserver作为回调方法。订阅的key的值发生变更后,当执行flush方法时,PreferencesObserver被触发回调。不再需要PreferencesObserver时请注销。
代码语言:javascript复制private class PreferencesObserverImpl implements Preferences.PreferencesObserver {
@Override
public void onChange(Preferences preferences, String key) {
if ("intKey".equals(key)) {
HiLog.info(LABLE, "Change Received:[key=value]");
}
}
}
// 订阅数据变化
PreferencesObserverImpl observer = new PreferencesObserverImpl();
preferences.registerObserver(observer);
// 修改数据
preferences.putInt("intKey", 3);
// 触发订阅者回调方法执行
preferences.flush();
// 修改数据后,observer的onChange方法会被回调
// 注销订阅
preferences.unRegisterObserver(observer);
移除Preferences实例。
从内存中移除指定文件对应的Preferences单实例。移除Preferences单实例时,应用不允许再使用该实例进行数据操作,否则会出现数据一致性问题。
代码语言:javascript复制DatabaseHelper databaseHelper = new DatabaseHelper(context);
String fileName = "name"; // fileName表示文件名,其取值不能为空,也不能包含路径。
databaseHelper.removePreferencesFromCache(fileName);
删除指定文件。
使用deletePreferences方法从内存中移除指定文件对应的Preferences单实例,并删除指定文件及其备份文件、损坏文件。删除指定文件时,应用不允许再使用该实例进行数据操作,否则会出现数据一致性问题。删除后,数据及文件将不可恢复。
代码语言:javascript复制DatabaseHelper databaseHelper = new DatabaseHelper(context);
String fileName = "name"; // fileName表示文件名,其取值不能为空,也不能包含路径。
boolean result = databaseHelper.deletePreferences(fileName);
移动指定文件。
从源路径移动文件到目标路径。移动文件时,应用不允许再操作该文件数据,否则会出现数据一致性问题。
代码语言:javascript复制Context targetContext = getContext();
DatabaseHelper databaseHelper = new DatabaseHelper(targetContext);
String srcFile = "srcFile"; // srcFile表示源文件名或者源文件的绝对路径,不能为相对路径,其取值不能为空。当srcFile只传入文件名时,srcContext不能为空。
String targetFile = "targetFile"; // targetFile表示目标文件名,其取值不能为空,也不能包含路径。
Context srcContext = getApplicationContext();
boolean result = databaseHelper.movePreferences(srcContext, srcFile, targetFile);