为了更具体地回答您的问题,这就是我在我的一个应用中备份房间数据库的方式。
1-检查读取/写入外部存储的权限。
2-关闭您的 RoomDatabase。在我的例子中,AppDatabase 指的是一个单例,其中包含最初构建房间数据库的逻辑。 AppDatabase.getInstance(this@MainActivity) 获取单例的当前实例及其当前数据库类,该类从 RoomDatabase 扩展而来。
3-然后基本上调用 dbInstance.close()。
private fun createBackup() {
val db = AppDatabase.getInstance(this@MainActivity)
db.close()
val dbFile: File = getDatabasePath(DATABASE_NAME)
val sDir = File(Environment.getExternalStorageDirectory(), "Backup")
val fileName = "Backup (${getDateTimeFromMillis(System.currentTimeMillis(), "dd-MM-yyyy-hh:mm")})"
val sfPath = sDir.path + File.separator + fileName
if (!sDir.exists()) {
sDir.mkdirs()
}
val saveFile = File(sfPath)
if (saveFile.exists()) {
Log.d("LOGGER ", "File exists. Deleting it and then creating new file.")
saveFile.delete()
}
try {
if (saveFile.createNewFile()) {
val bufferSize = 8 * 1024
val buffer = ByteArray(bufferSize)
var bytesRead: Int
val saveDb: OutputStream = FileOutputStream(sfPath)
val indDb: InputStream = FileInputStream(dbFile)
do {
bytesRead = indDb.read(buffer, 0, bufferSize)
if (bytesRead < 0)
break
saveDb.write(buffer, 0, bytesRead)
} while (true)
saveDb.flush()
indDb.close()
saveDb.close()
}
} catch (e: Exception) {
e.printStackTrace()
}
}
您必须在其中包含保存文件
try {
//backup process
}
} catch (e: Exception) {
e.printStackTrace()
}
按发生错误的顺序并避免应用崩溃。
并从 currentTimeMillis 获取日期
使用这个功能
fun getDateTimeFromMillis(millis: Long, pattern: String): String {
val simpleDateFormat = SimpleDateFormat(pattern, Locale.getDefault()).format(Date())
return simpleDateFormat.format(millis)
}
重新定位 Db 的代码
将文件对象传递给 Uri.fromFile
try {
val fileUri: Uri = Uri.fromFile(file)
val inputStream = contentResolver.openInputStream(fileUri)
println("restoring ")
restoreDatabase(inputStream);
inputStream?.close()
} catch (e: IOException) {
println( e.message)
e.printStackTrace()
}
**或返回结果并带有开始活动的结果**
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 12 && resultCode == RESULT_OK && data != null) {
Uri fileUri = data.getData();
try {
assert fileUri != null;
InputStream inputStream = getContentResolver().openInputStream(fileUri);
restoreDatabase(inputStream);
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
恢复数据库功能
private fun restoreDatabase(inputStreamNewDB: InputStream?) {
val db = AppDatabase.getInstance(this@MainActivity)
db.close()
val oldDB = getDatabasePath(DATABASE_NAME)
if (inputStreamNewDB != null) {
try {
copyFile(inputStreamNewDB as FileInputStream?, FileOutputStream(oldDB))
println("restore success")
} catch (e: IOException) {
Log.d("BindingContextFactory ", "ex for is of restore: $e")
e.printStackTrace()
}
} else {
Log.d("BindingContextFactory ", "Restore - file does not exists")
}
}
现在您需要将文件从备份复制到真实的 db 文件中
使用复制文件
@Throws(IOException::class)
fun copyFile(fromFile: FileInputStream?, toFile: FileOutputStream) {
var fromChannel: FileChannel? = null
var toChannel: FileChannel? = null
try {
fromChannel = fromFile?.channel
toChannel = toFile.channel
fromChannel?.transferTo(0, fromChannel.size(), toChannel)
} finally {
try {
fromChannel?.close()
} finally {
toChannel?.close()
}
}
}