Android Sqlite База данных copyDatabase функция Пути - PullRequest
0 голосов
/ 23 сентября 2019

Я использую приведенный ниже код для копирования базы данных sqlite, просто удивляясь, как правильно кодировать пути, так как Android Studio рекомендует не жестко кодировать пути, как показано на прилагаемом изображении.В большинстве ответов здесь также используются жестко закодированные пути / пути данных / данных.

    companion object {

    private val DATABASE_VERSION = 1
    private val DATABASE_NAME = "books.db"

    @JvmStatic
    fun copyDatabase(context: Context) {

        LogUtil.loge("copyDatabase")
        try {
            var dir = "/data/data/" + context.getPackageName() + "/databases"
            if (Build.VERSION.SDK_INT >= 24){
                dir = context.dataDir.absolutePath + "/databases/"
            }
            if(!File(dir).exists()){
                LogUtil.loge("databases dir not exist")
                File(dir).mkdir()
            }
            val outFileName = context.getDatabasePath(DATABASE_NAME)
            val myOutput = FileOutputStream(outFileName)
            val buffer = ByteArray(1024)
            var length: Int
            val myInput = context.assets.open("databases/$DATABASE_NAME")
            length = myInput.read(buffer)
            while (length > 0) {
                myOutput.write(buffer, 0, length)
                length = myInput.read(buffer)
            }
            myInput.close()
            myOutput.flush()
            myOutput.close()
        } catch (e: IOException) {
            e.printStackTrace()
            LogUtil.loge("unable to copy database")
        }
    }
}

enter image description here

1 Ответ

1 голос
/ 23 сентября 2019

Сначала используйте Context * getDatabasePath("databasename"); для создания объекта File, затем используйте getParentFile для File, чтобы получить каталог как файл, а затем как основу для OutputStream.Все, что вам нужно сделать, это жестко кодировать имя базы данных (и папку баз данных в папке ресурсов).

getDatabasePath

например что-то вроде: -

private fun dbcopy(context: Context) {

    val dbfile = File(context.getDatabasePath(DATABASE_NAME).path)
    if (!dbfile.parentFile.exists()) {
        dbfile.parentFile.mkdirs()
    }
    try {
        val os = FileOutputStream(dbfile)
        // and so on
    } catch (e: IOException) {

    }

}

PS нет необходимости проверять версию, вышеописанное работает для всех известных мне версий (хотя и конвертированных из Java).

Вам потребуется жесткий код базы данных при открытии ресурса, поскольку он не является стандартной / предопределенной / должен использовать папку.

Я склонен выполнять проверку каталога и создавать его как часть проверки, если база данных существует, например: -

private fun checkDataBase(context: Context): Boolean {

    val db = File(context.getDatabasePath(DATABASE_NAME).path) //Get the file name of the database
    if (db.exists()) return true // If it exists then return doing nothing

    val dbdir = db.parentFile
    // If the directory does not exist then make the directory (and higher level directories)
    if (!dbdir.exists()) {
        db.parentFile.mkdirs()
        dbdir.mkdirs()
    }
    return false
}

Ниже приводится полный помощник (без каких-либо методов доступа к базе данных), который скопирует базу данных из папки базы данных активов, если база данных не существует: -

class MyDBHelper(internal var myContext: Context) : SQLiteOpenHelper(myContext, DATABASE_NAME, null, DATABASE_VERSION) {
    internal var buffer_size = 1024 * 4

    init {
        if (!checkDataBase()) {
            copyDataBase()
        }
    }

    override fun onCreate(db: SQLiteDatabase) {}

    override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {}

    private fun checkDataBase(): Boolean {

        val db = File(myContext.getDatabasePath(DATABASE_NAME).path) //Get the file name of the database
        Log.d("DBPATH", "DB Path is " + db.path) //TODO remove for Live App
        if (db.exists()) return true // If it exists then return doing nothing

        // Get the parent (directory in which the database file would be)
        val dbdir = db.parentFile
        // If the directory does not exits then make the directory (and higher level directories)
        if (!dbdir.exists()) {
            db.parentFile.mkdirs()
            dbdir.mkdirs()
        }
        return false
    }

    private fun copyDataBase() {
        try {

            val myInput = myContext.assets.open("databases" + File.separator + DATABASE_NAME) // Open the Asset file
            val outfile = File(myContext.getDatabasePath(DATABASE_NAME).toString())
            val myOutput = FileOutputStream(outfile)
            //transfer bytes from the inputfile to the outputfile
            val buffer = ByteArray(buffer_size)
            var length = myInput.read(buffer)
            while (length > 0) {
                myOutput.write(buffer, 0, length)
                length = myInput.read(buffer)
            }
            //Close the streams
            myOutput.flush()
            myOutput.close()
            myInput.close()
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }

    companion object {
        private val DATABASE_NAME = "thedatabase.db"
        private val DATABASE_VERSION = 1
    }
}
  • Обратите внимание, что вместо жесткого кодирования разделителя файлов он также получается в соответствии с системным значением.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...