我正在使用下面的代码来复制 sqlite 数据库,只是想知道路径的正确编码是什么,因为 Android Studio 建议不要对路径进行硬编码,如所附图像所示。这里的大多数答案也使用了硬编码的/data/data 路径。
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")
}
}
}
最佳答案
首先使用Context的getDatabasePath("databasename");
创建一个File对象,然后使用File的getParentFile将目录获取为文件,然后作为OutputStream的基础。您需要做的就是对数据库名称(以及 Assets 文件夹中的数据库文件夹)进行硬编码。
例如类似的东西:-
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) {
}
}
附注无需检查版本,以上内容适用于我所知道的所有版本(尽管是从 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
}
以下是一个完整的帮助程序(减去任何访问数据库的方法),如果数据库不存在,它将从 Assets 数据库文件夹中复制数据库:-
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
}
}
- 请注意,文件分隔符不是硬编码,而是根据系统值获取。
关于java - Android Sqlite 数据库复制数据库函数路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58068172/