首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >房间持久化库是否可以压缩成预打包的数据库?

房间持久化库是否可以压缩成预打包的数据库?
EN

Stack Overflow用户
提问于 2021-06-18 16:29:38
回答 1查看 58关注 0票数 0

我有一个大约150mb的大型数据库。我是否可以将压缩版本的数据库(例如zip )放在资产文件夹中以供空间使用,或者这是不可能的吗?

PS: android studio的apk压缩是不够的

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-06-20 02:43:31

首先,您需要一个函数,它可以将归档文件解压缩到某个目录:

代码语言:javascript
复制
// unzip(new File("/sdcard/whatToUnzip.zip"), new File("/toThisFolder"));
fun unzip(zipFile: File, targetDirectory: File) {
    unzip(BufferedInputStream(FileInputStream(zipFile)), targetDirectory)
}

fun unzip(zipInputStream: InputStream, targetDirectory: File) {
    try {//BufferedInputStream(zipFileStream)
        ZipInputStream(zipInputStream).use { zipInput ->
            var zipEntry: ZipEntry
            var count: Int
            val buffer = ByteArray(65536)
            while (zipInput.nextEntry.also { zipEntry = it } != null) {
                val file = File(targetDirectory, zipEntry.name)
                val dir: File? = if (zipEntry.isDirectory) file else file.parentFile
                if (dir != null && !dir.isDirectory && !dir.mkdirs()) throw FileNotFoundException(
                    "Failed to ensure directory: " + dir.absolutePath
                )
                if (zipEntry.isDirectory) continue
                FileOutputStream(file).use { fileOutput ->
                    while (zipInput.read(buffer).also { count = it } != -1) fileOutput.write(
                        buffer,
                        0,
                        count
                    )
                }
            }
        }
    } catch (e: Exception) {
        e.printStackTrace()
    }
}

我是从that stackoverflow's thread.获取的,请阅读一个帖子以获取更多详细信息。然后,我添加了两个方法来处理app资产文件夹中的文件:

代码语言:javascript
复制
fun unzipAsset(assetsFilePath: String, context: Context, targetDirectory: File) {
    unzip(context.assets.open(assetsFilePath), targetDirectory)
}

fun Context.unzipAsset(assetsFilePath: String, targetDirectory: File) = unzipAsset(
    assetsFilePath,
    this,
    targetDirectory
)

现在我们可以将文件解压缩到文件夹中。当我使用Room.databaseBuildercreateFromAsset或createFromFile方法时,为了避免按房间复制解压缩的数据库文件,我想将文件解压缩到空间用来存储数据库文件的应用程序databases文件夹中。这就是为什么我需要其他方法来获取db文件夹路径并检查db文件何时已经存在:

代码语言:javascript
复制
fun Context.databaseFolderPath(): File? = this.getDatabasePath("any.db").parentFile

// name – The name of the database file.
fun Context.isRoomDbFileExist(name: String): Boolean  {
    return this.getDatabasePath(name)?.exists() ?: false
}

现在,如何一起使用all thinks:

代码语言:javascript
复制
abstract class AppDatabase : RoomDatabase() {

companion object {

        private const val DB_NAME = "sunflower-db"

        // Create and pre-populate the database. See this article for more details:
        // https://medium.com/google-developers/7-pro-tips-for-room-fbadea4bfbd1#4785
        private fun buildDatabase(context: Context): AppDatabase {
            if(!context.isRoomDbFileExist(DB_NAME)) {
                // unzip db file to app's databases directory to avoid copy of unzipped file by room
                context.unzipAsset("sunflower-db.zip", context.databaseFolderPath()!!)
                // or unzip(File("your file"), context.databaseFolderPath()!!)
            }
            return Room.databaseBuilder(context, AppDatabase::class.java, DB_NAME)
                //.createFromAsset(DB_NAME) // not zipped db file
                .build()
        }
    }
}

我在nice open source project - sunflower上测试了这段代码。接下来,我想显示带有项目结构的屏幕,其中sunflower-db.zip位于:

上面的方法是可行的,但是你不应该把这个样本看作是正确的或者最佳的解决方案。你应该考虑避免从主线程解压缩进程。如果你实现自己的SupportSQLiteOpenHelper.Factory(看起来很复杂),可能会更好。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68031876

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档