我需要移动一些文件以便我的应用程序进行下一次更新。这些“文件”主要由JPEG组成,这些JPEG由我的数据库中的专用表进行跟踪。基于这一事实,我决定使用Migration
对象来处理数据库迁移和文件重定位。
我的Migration
课程的简化摘录:
class VersionOneToTwo(private val appDataDir: File) : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
database.beginTransaction()
try {
renameUriColumnInMedia(database)
updatePathDataInMedia(database)
moveEntryPhotoFilesToNewFolder(appDataDir)
database.setTransactionSuccessful()
} catch (e: Exception) {
throw MigrationFailed(1, 2, e)
} finally {
database.endTransaction()
}
}
private fun renameUriColumnInMedia(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE media RENAME TO old_media ...")
database.execSQL("CREATE TABLE `media` ...")
database.execSQL("INSERT INTO `media` ...")
database.execSQL("DROP TABLE old_media ...")
}
private fun updatePathDataInMedia(database: SupportSQLiteDatabase) {
database.execSQL("UPDATE media SET `path` = REPLACE(`path`, '/Photos/', '/entry-photos/') ...")
}
private fun moveEntryPhotoFilesToNewFolder(appDataDir: File) {
moveFiles(File(appDataDir, "Photos"), File(appDataDir, "entry-photos"))
}
private fun moveFiles(sourceDir: File, targetDir: File) {
if (sourceDir.exists().not()) {
// This operation is not necessary.
return
}
if (sourceDir.isDirectory.not()) {
throw IllegalArgumentException("The given source directory is not a valid directory.")
}
if (targetDir.mkdirs().not()) {
throw IOException("The creation of target directory has failed.")
}
sourceDir.listFiles().forEach {
val movedFile = File(targetDir, it.name)
it.copyTo(movedFile, true)
}
sourceDir.deleteRecursively()
}
}
疯狂的是,每当它实际移动文件时(调用moveEntryPhotoFilesToNewFolder()
时)我的文件似乎都丢失了:
sourceDir.exists()
moveEntryPhotoFilesToNewFolder()
返回false
sourceDir.listFiles()
在同一方法中返回null
adb shell; run-as <mypackage>; ls files;
什么都没打印我试图注释掉迁移的文件重定位部分,确实我的应用程序会运行。但是文件仍然会丢失。
我错过了一些明显的东西吗?我检查并仔细检查;我的项目中没有其他代码在我上面显示的delete()
课程之外调用deleteRecursively()
或Migration
。
p.s。,appDataDir
这里是Context.getFilesDir()