LevelDB 在 Windows 10 UWP 应用中的使用

LevelDB 是一个由 Google 开发的快速键值存储库,它提供了一个从字符串键到字符串值的有序映射。本文将向您介绍如何在 Windows 10 Universal Platform (UWP) 应用中使用 LevelDBWinRT 来实现 LevelDB 的功能。

为什么选择 LevelDB

LevelDB 提供了以下基本特性:

  • 键和值可以是任意字节数组(切片)
  • 数据按键存储和排序
  • 调用者可以提供自定义比较函数来覆盖排序顺序(实验性支持)
  • 基本的 Get(key)/Put(key, value)/Delete(key) 支持
  • 原子批处理操作可以进行多个更改
  • 用户可以创建临时快照以获取数据的一致视图
  • 迭代器支持,包括向前和向后迭代
  • WriteOptions、ReadOptions、Options 的基本包装器
  • 内置压缩支持 Snappy
  • 自定义比较器支持(实验性)
  • 支持 ARM、x86 和 x64 架构
  • 支持 Windows 8 和 WP 8.1

安装 LevelDBWinRT

您可以通过 NuGet 安装 LevelDBWinRT。或者在您的包管理控制台中运行以下命令:

Install-Package LevelDB.UWP

创建数据库

创建和打开数据库非常简单。首先导入LevelDBWinRT 命名空间:

using LevelDBWinRT;

每个数据库对应一个文件,创建数据库意味着创建一个 LevelDB 文件。操作数据库的主要类是 LevelDBWinRT.DB。构造函数接受两个参数:第一个是创建数据库的选项,第二个是文件路径。例如:

var db = new DB(new Options { CreateIfMissing = true }, "foo.db");

这将在 ApplicationData.Current.LocalFolder.Path 下创建数据库文件 foo.db。如果您没有指定文件的完整路径(即它不以 X: 开头,其中 X 是驱动器字母),则默认文件夹被假定为 ApplicationData.Current.LocalFolder.Path。如果您没有访问该文件夹的权限或路径不存在,则操作将失败。在失败的情况下,会抛出一个 COMException,其中包含捕获的错误代码和错误消息。如果您只想打开数据库(如果存在),否则失败,请移除 CreateIfMissing 选项。

处理数据库

DB 类是可处置的。因此,调用 Dispose() 实际上会删除底层的 leveldb 对象,从而正确释放内存并关闭任何打开的文件句柄。所以一旦您完成使用数据库,请确保将其处置掉。

db.Dispose();

不处置数据库对象并丢失对对象的引用会将其留给 GC 进行清理,这可能会导致不希望的结果,因此请确保正确处置您的对象。

添加和删除条目

数据库打开后,可以轻松地向其中添加和删除条目。要向 LevelDB 添加或删除任何内容,您需要提供切片,一个键切片和一个值切片。切片在 LevelDB 术语中就是字节数组的包装器。

LevelDBWinRT.Slice 是您可以使用的类,可以从 byte[] 或 string 创建切片。尽管 byte[] 足以生成任何类型的切片,但由于其频繁使用,也提供了 string 重载。插入键值对 "foo" => "bar" 非常简单:

db.Put(new WriteOptions(), Slice.FromString("foo"), Slice.FromString("bar"));

您可以使用 WriteOptions 来控制是否立即将更改同步到磁盘。删除 "foo" 也很简单:

db.Delete(new WriteOptions(), Slice.FromString("foo"));

立即将更改刷新到磁盘非常简单,只需在任何写操作中将 Sync 设置为 true,例如:

db.Put(new WriteOptions{ Sync = true }, Slice.FromString("foo"), Slice.FromString("bar"));

字节和切片

到目前为止,可以看到切片是 LevelDB 的一个重要部分,字节是切片的基本部分。这里的一个设计选择是只提供两种方法来创建切片。有两种静态方法,Slice.FromString 和 Slice.FromByteArray。第一种方法 Slice.FromString 因为频繁使用,而 Slice.FromByteArray 支持几乎所有其他内容。反向方法也可用,ToByteArray 和 AsString 可以将值转换回。您可以使用 BitConverter 和任何类型的序列化程序将复杂对象转换为 byte[],LevelDB 只是让您处理序列化业务。

读取值

读取单个值也非常简单。您可以简单地执行:

Slice slice = db.Get(new ReadOptions(), Slice.FromString("foo")); string sliceValue = slice.AsString();

// "bar"

ReadOptions 再次提供了一些选项,让您可以更多地控制您的读取。详细信息将在另一节中讨论。

批量写入

就像任何好的数据库一样,LevelDB 提供了在单个写操作中执行批量插入和删除的选项(原子操作)。WriteBatch 类由 LevelDB 提供,您可以创建并提交一个批次,如下所示:

using(var batch = new WriteBatch()) { batch.Put(Slice.FromString("foo"), Slice.FromString("bar")); batch.Delete(Slice.FromString("del")); db.Write(new WriteOptions(), batch); }

一个更复杂的例子可以是:

using(var writeBatch = new WriteBatch()) { for(var i = 0; i < 10; i++) { writeBatch.Put(Slice.FromString("Key"+i), Slice.FromByteArray(BitConverter.GetBytes(i))); } db.Write(new WriteOptions(), writeBatch); }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485