Android 从资产文件夹复制数据库会创建空数据库

Android 从资产文件夹复制数据库会创建空数据库,android,kotlin,Android,Kotlin,将现有数据库从“资产”文件夹复制到“数据库”文件夹时遇到问题。最初的数据库是5.9MB,但使用下面的代码,它创建了一个12KB的数据库,其中包含android\u元数据表,该表已经在我的数据库中 代码如下: class Database(private val ctx: Context = App.instance) : ManagedSQLiteOpenHelper(ctx, DB_NAME, null, DB_VERSION), AnkoLogger { companion obje

将现有数据库从“资产”文件夹复制到“数据库”文件夹时遇到问题。最初的数据库是5.9MB,但使用下面的代码,它创建了一个12KB的数据库,其中包含
android\u元数据
表,该表已经在我的数据库中

代码如下:

class Database(private val ctx: Context = App.instance) : ManagedSQLiteOpenHelper(ctx, DB_NAME, null, DB_VERSION), AnkoLogger {
    companion object {
        val instance by lazy { Database() }
        private const val DB_NAME = "dex.db"
        private const val DB_VERSION = 1
    }

    override fun onCreate(db: SQLiteDatabase) {
        if (!ctx.getDatabasePath(DB_NAME).exists()) {
            info("Creating database ${db.path}.")
            copyDatabase()
        }
    }

    override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
        if (newVersion > oldVersion) {
            info("Updating database ${db.path} from version $oldVersion to version $newVersion.")
            copyDatabase()
        }
    }

    private fun copyDatabase() {
        info("Copying database to data folder.")
        ctx.assets.open(DB_NAME).buffered().use { input ->
            FileOutputStream(ctx.getDatabasePath(DB_NAME)).use { out ->
                input.copyTo(out)
            }
        }
    }
}

使用Android Studio中的设备文件资源管理器手动复制数据库,并使用来查询数据库工作得很好,但是使用上面的代码,查询任何表都不会抛出
错误。

为AssetDBOpenHelper创建一个类。试试下面的方法。这对我来说很好

class AssetDBOpenHelper(private val context: Context) {    
companion object {    
    private val DB_NAME = "asset_db_name.db"
}

fun openDatabase(): SQLiteDatabase {
    val dbFile = context.getDatabasePath(DB_NAME)    

    if (!dbFile.exists()) {
        try {
           val checkDB = context.openOrCreateDatabase(DB_NAME, Context.MODE_PRIVATE,null)
            checkDB?.close()
            copyDatabase(dbFile)
        } catch (e: IOException) {
            throw RuntimeException("error", e)
        }    
    }
    return SQLiteDatabase.openDatabase(dbFile.path, null, SQLiteDatabase.OPEN_READWRITE)
}

@SuppressLint("WrongConstant")
private fun copyDatabase(dbFile: File) {
    val `is` = context.assets.open(DB_NAME)
    val os = FileOutputStream(dbFile)    
    val buffer = ByteArray(1024)
    while (`is`.read(buffer) > 0) {
        os.write(buffer)
    }    
    os.flush()
    os.close()
    `is`.close()
}
然后在活动中打开或创建数据库

val adb = AssetDatabaseOpenHelper(this)
adb.openDatabase()

这可能行得通,但即使Java和Kotlin是可互操作的,我也不认为这是OP所要求的解决方案for@user2340612-很抱歉给您带来不便。我将语言更改为kotlin&后期编辑。请按照stackoverflow指导原则进行更新投票,如果您发现它符合您的期望没有问题,现在语言匹配,但是我认为如果在上一次迭代中
缓冲区
未完全填满,您的
循环将出现问题,因为您将编写脏字节。您是否设法解决了这个问题?如果你能更新我们,这将是非常感谢,因为我正试图实现一个数据库副本以及。