[官文翻译]Dart轻量超快键值数据库Hive - 高级

837 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第19天,点击查看活动详情


原文链接:

pub: hive | Dart Package (flutter-io.cn)

pub译文: [译]纯Dart键值(对象)数据库hive - 掘金 (juejin.cn)

译时版本: hive 2.1.0


延迟 box

默认情况下,一个 box 的所有内容都会在打开时存储到内存中。对于中小型的 box 该行为是很棒的,因为不用异步调用就能访问它们的内容。

对于大型的 box 或者内存控制非常严格的应用来说,延迟加载值可能会有用。当延迟 box 打开时,它的所有键会被读取和存储到内存中。一旦访问了一个值,Hive 会知道它在磁盘上的确切位置并获取该值。

var lazyBox = await Hive.openLazyBox('myLazyBox');

var value = await lazyBox.get('lazyVal');

要获取一个已经打开的延迟 box 调用:

var lazyBox = Hive.lazyBox('myLazyBox');

加密 box

有时候,在磁盘上安全地存储数据很有必要。Hive 开箱支持 AES-256 加密 (字面意思)。

唯一需要是一个 256 位 (32 字节) 的加密键。 Hive 提供了一个辅助函数使用 Fortuna 随机数生成器用于生成安全的加密键。

只需在打开 box 时传递该键:

import 'dart:convert';
import 'package:hive/hive.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';

void main() async {
  final FlutterSecureStorage secureStorage = const FlutterSecureStorage();
  var containsEncryptionKey = await secureStorage.containsKey(key: 'key');
  if (!containsEncryptionKey) {
    var key = Hive.generateSecureKey();
    await secureStorage.write(key: 'key', value: base64UrlEncode(key));
  }
  
  var encryptionKey = base64Url.decode(await secureStorage.read(key: 'key'));
  print('Encryption key: $encryptionKey');

  var encryptedBox = await Hive.openBox('vaultBox', encryptionCipher: HiveAesCipher(encryptionKey));
  encryptedBox.put('secret', 'Hive is cool');
  print(encryptedBox.get('secret'));
}

上面的示例使用 flutter_secure_storage 包存储了加密键,但是你可以使用任何想使用的包/方法用于应用关闭时安全存储加密键。

压缩

Hive 是只添加的数据存储。当更改或删除一个值时,变动会写到 box 文件的末尾。不久或者之后, box 文件就会占用比实际所需更多的磁盘空间。Hive 可能会自动地随时 "压缩" 来关闭文件中的 "洞" 。("洞"在这里指更改删除后文件中出现的不被使用的空间)

如果在关闭 box 之前手动进行压缩可能有利于缩短应用的启动时间。

var box = Hive.box('myBox');
await box.compact();
await box.close();

可以指定你自己的规则用于自动压缩。只需要在打开 box 时传递 compactionStrategy (压缩策略)参数:

var box = await Hive.openBox('myBox', compactionStrategy: (entries, deletedEntries) {
  return deletedEntries > 50;
});

上面的 compactionStrategy 会在50个键被覆写或删除时压缩 box 。

严禁在压缩策略中访问 box 。