Docs 菜单
Docs 主页
/ /
Atlas Device SDKs
/ /

配置并打开 Realm - Kotlin SDK

在此页面上

  • Realm 文件
  • 辅助文件
  • 打开 Realm
  • 打开默认 Realm
  • 打开内存中 Realm
  • 自定义 Realm 配置
  • 将初始数据添加到 Realm
  • 查找 Realm 文件路径
  • 关闭 Realm
  • 将数据复制到 New Realm

本页介绍 Realm 文件以及如何配置、打开和关闭仅在本地持久保存数据的 Realm。 要打开使用 Device Sync 与 Atlas 同步数据的 Realm,请参阅打开同步 Realm。

Realm是 Realm 中用于组织数据的核心数据结构。每个 Realm 都是 Realm 对象的集合:您在应用程序中使用的对象以及描述这些对象的其他元数据。每个 Realm 对象类型都有一个基于您定义的对象模型的对象模式。

Realm 模式是 Realm 可能包含的有效对象模式的列表。 您可以在打开 Realm 时指定模式。 如果在打开 Realm 时已包含数据,则 Realm 会验证每个对象,以确保为其类型提供了对象模式,并且满足模式中指定的所有约束。

Realm 将 Realm 中每个对象和类型的二进制编码版本存储在单个 .realm文件中。当您打开一个域时,Realm会创建.realm文件(如果该文件尚不存在)。该文件位于特定路径,您可以在打开 Realm 时定义该路径。

提示

在 Realm Studio 中处理 Realm 文件

如果您不想创建.realm文件或其关联的辅助文件,可以打开一个内存中 Realm。有关更多信息,请参阅打开内存中 Realm部分。

Realm 会为每个 Realm 创建附加文件:

  • realm 文件,后缀为 "realm",例如 default.realm :包含对象数据。

  • 锁定文件,后缀为 "lock",例如 default.realm.lock :跟踪 Realm 中哪些数据版本正在使用中。 这可以防止 Realm 回收客户端应用程序仍在使用的存储空间。

  • note 文件,后缀为 "note",例如 default.realm.note :启用线程间和进程间通知。

  • 管理文件,后缀为“管理”,例如 default.realm.management :内部状态管理。

删除这些文件具有重要意义。有关删除.realm或辅助文件的更多信息,请参阅:删除 Realm。

要打开 Realm,请创建一个定义 Realm 详细信息的RealmConfiguration对象。 然后,将生成的RealmConfiguration传递给Realm.open()。

您可以使用默认配置值打开 Realm,也可以使用其他配置选项构建RealmConfiguration 。 但是,您必须传递一个模式参数,其中包括要在 Realm 中使用的所有对象类

使用所需配置打开 Realm 后,您可以根据定义的模式读取和写入数据

本页上的示例引用了以下 Realm 对象:

class Frog : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
}
class Person : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
}

要使用默认配置值打开 Realm,请使用RealmConfiguration.create() 。方法。您只需定义一组对象类作为 Realm 模式。然后,将RealmConfiguration传递给Realm.open()。

以下示例在默认路径中打开一个default.realm文件,其模式包括FrogPerson类:

// Creates a realm with default configuration values
val config = RealmConfiguration.create(
// Pass object classes for the realm schema
schema = setOf(Frog::class, Person::class)
)
// Open the realm with the configuration object
val realm = Realm.open(config)
Log.v("Successfully opened realm: ${realm.configuration.name}")
// ... use the open realm ...

如果没有为 Realm 文件定义目录,则使用平台的默认应用存储位置。您可以使用以下命令查找平台的默认目录:

  • Android: Context.getFiles()

  • Java虚拟机(JVM): System.getProperty("user.dir")

  • macOS: platform.Foundation.NSFileManager.defaultManager.currentDirectoryPath

  • iOS:

    NSFileManager.defaultManager.URLForDirectory(
    NSDocumentDirectory,
    NSUserDomainMask,
    null,
    true,
    null
    )

您可以完全在内存中打开 Realm,这样不会创建.realm文件或其关联的辅助文件。相反,SDK 会在 Realm 打开时将对象存储在内存中,然后在关闭所有实例时丢弃数据。

要打开在不写入文件的情况下运行的 Realm,请通过RealmConfiguration.Builder 并使用inMemory属性来构建RealmConfiguration 。 然后,将生成的RealmConfiguration传递给Realm.open():

// Create the in-memory realm configuration
val config = RealmConfiguration.Builder(
schema = setOf(Frog::class, Person::class)
)
.inMemory()
.build()
// Open the realm with the configuration object
val realm = Realm.open(config)
Log.v("Successfully opened an in-memory realm")
// ... use the open realm ...

注意

内存中的 Realm 不会被持久化

由于内存中的 Realm 不会持久保存,因此,只要您想要访问数据,请确保至少有一个处于打开状态的 Realm 实例。 关闭内存中 Realm 的最后一个实例后,数据就不再可用。

您可以向RealmConfiguration添加可选参数,以控制要打开的 Realm 的细节,包括:

有关特定配置实现的更多信息,请参阅管理 Realm 文件 - Kotlin SDK。

要使用非默认值配置 Realm,请通过RealmConfiguration.Builder.build()创建RealmConfiguration 并传递您要设置的任何属性。 然后,将生成的RealmConfiguration传递给Realm.open()。

在以下示例中, RealmConfiguration指定自定义名称和目录 ("my-directory-path/myRealmName.realm") 以及加密密钥:

// Create a realm configuration with configuration builder
// and pass all optional arguments
val config = RealmConfiguration.Builder(
schema = setOf(Frog::class, Person::class)
)
.name("myRealmName.realm")
.directory("my-directory-path")
.encryptionKey(myEncryptionKey)
.build()
// Open the realm with the configuration object
val realm = Realm.open(config)
Log.v("Successfully opened realm: ${realm.configuration.name}")
// ... use the open realm ...

您可以使用initialDataCallback将初始数据添加到 Realm。首次打开 Realm 时会触发该回调。

val config = RealmConfiguration.Builder(
schema = setOf(Frog::class, Person::class)
)
.initialData {
copyToRealm(Frog().apply { name = "Kermit" })
copyToRealm(Person().apply { name = "Jim Henson" })
}
.build()
val realm = Realm.open(config)
Log.v("Successfully opened realm: ${realm.configuration.name}")
// Opened realm includes the initial data
val initialFrog = realm.query<Frog>().find().first()
val initialPerson = realm.query<Person>().find().first()
Log.v("Realm initialized with: ${initialFrog.name} and ${initialPerson.name}")

要查找.realm文件的文件路径,请使用realm.configuration.path属性:

val realmPath = realm.configuration.path
Log.v("Realm path: $realmPath")

您可以使用realm.close()关闭一个 Realm。 此方法会阻塞,直到 Realm 上的所有写事务都完成为止。

realm.close()

警告

关闭 Realm 以防止内存泄漏

请务必关闭 Realm 实例以释放资源。 未能关闭 Realm 可能会导致OutOfMemoryError

要将数据从现有 Realm 复制到具有不同配置选项的新 Realm,请将新配置传递给Realm.writeCopyTo()方法。例如,您可以通过复制数据来备份本地 Realm 或将同步 Realm 转换为本地 Realm。

您可以将数据复制到使用相同配置的 Realm:

  • 本地 Realm 到本地 Realm

  • 内存中 Realm 到内存中 Realm

  • 同步 Realm 到同步 Realm

您可以将数据复制到使用不同同步配置的 Realm:

  • 本地 Realm 到基于分区的同步 Realm

  • 同步 Realm 到本地域

  • 将同步 Realm 到其他用户的同步 Realm

警告

无法将数据从本地 Realm 复制到 Flexible Sync Realm。 不能在不同的同步配置类型之间复制,例如 从 基于分区的同步 到Flexible Sync 。

您还可以合并对配置的更改。例如,您可以将数据从未加密的内存中同步 Realm 复制到加密的本地 Realm。

使用 Realm.writeCopyTo() 时需要注意的一些其他注意事项:

例子

将数据从 Flexible Sync Realm 复制到本地 Realm

// Instantiate the synced realm with your App ID
val app = App.create(YOUR_APP_ID)
runBlocking {
val user = app.login(credentials)
// Create the synced realm configuration
val syncConfig = SyncConfiguration.Builder(user, setOf(Frog::class))
.initialSubscriptions { realm ->
add(realm.query<Frog>(),"all-frogs")
}
.build()
// Open the synced realm and add data to it
val syncRealm = Realm.open(syncConfig)
Log.v("Successfully opened realm: ${syncRealm.configuration.name}")
syncRealm.write {
this.copyToRealm(Frog().apply {
name = "Kermit"
})
}
// Wait for write to sync
syncRealm.syncSession.uploadAllLocalChanges(30.seconds)
// Create the local realm
val localConfig = RealmConfiguration.Builder(setOf(Frog::class))
.name("local.realm")
.build()
// Copy data from synced realm to the new realm
syncRealm.writeCopyTo(localConfig)
// Close the synced realm when you're done copying
syncRealm.close()
// Open the new local realm
val localRealm = Realm.open(localConfig)
// Copied Frog object is available in the new realm
val frog = localRealm.query<Frog>().find().first()
Log.v("Copied Frog: ${frog.name}")
localRealm.close()
}

您还可以在复制的域配置中加入新的加密密钥,或从新配置中删除加密密钥。

例子

将数据从未加密复制到加密 Realm

runBlocking {
// Create the unencrypted realm
val unencryptedConfig = RealmConfiguration.Builder(setOf(Frog::class))
.name("unencrypted.realm")
.build()
// Open the realm and add data to it
val unencryptedRealm = Realm.open(unencryptedConfig)
unencryptedRealm.write {
this.copyToRealm(Frog().apply {
name = "Kermit"
})
}
// ... Generate encryption key ...
// Create the encrypted realm
val encryptedConfig = RealmConfiguration.Builder(setOf(Frog::class))
.name("encrypted.realm")
.encryptionKey(encryptionKey)
.build()
// Copy data from `unencryptedRealm` to the new realm
// Data is encrypted as part of the copy process
unencryptedRealm.writeCopyTo(encryptedConfig)
// Close the original realm when you're done copying
unencryptedRealm.close()
// Open the new encrypted realm
val encryptedRealm = Realm.open(encryptedConfig)
// Copied Frog object is available in the new realm
val frog = encryptedRealm.query<Frog>().find().first()
Log.v("Copied Frog: ${frog.name}")
encryptedRealm.close()
}

例子

将数据从内存中复制到本地 Realm

runBlocking {
// Create the in-memory realm
val inMemoryConfig = RealmConfiguration.Builder(setOf(Frog::class))
.name("inMemory.realm")
.inMemory()
.build()
// Open the realm and add data to it
val inMemoryRealm = Realm.open(inMemoryConfig)
inMemoryRealm.write {
this.copyToRealm(Frog().apply {
name = "Kermit"
})
}
// Create the local realm
val localConfig = RealmConfiguration.Builder(setOf(Frog::class))
.name("local.realm")
.build()
// Copy data from `inMemoryRealm` to the new realm
inMemoryRealm.writeCopyTo(localConfig)
// Close the original realm when you're done copying
inMemoryRealm.close()
// Open the new local realm
val localRealm = Realm.open(localConfig)
// Copied Frog object is available in the new realm
val frog = localRealm.query<Frog>().find().first()
Log.v("Copied Frog: ${frog.name}")
localRealm.close()
}

后退

使用 Device Sync 对数据建模