You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Room数据库导入JSON文件时触发FileNotFoundException异常求助

问题排查与解决方案

你的问题根源在于Room的createFromAsset()方法的路径使用错误,下面详细说明问题原因和两种解决办法:

为什么会报FileNotFoundException?

createFromAsset()是专门用来读取项目assets目录下的文件的,而你把cars_sample.json放在了res/raw目录里,这两个目录的文件访问规则完全不同:

  • res/raw里的文件会被Android编译系统分配资源ID(比如R.raw.cars_sample),不能通过文件路径直接访问
  • assets目录下的文件则是按原始文件名和路径访问,不会生成资源ID

你传入的"app/res/raw/cars_sample.json"既不是assets目录下的正确路径,也不符合res/raw的访问方式,所以系统找不到文件。


解决方案1:将JSON文件移到assets目录(推荐)

这是最符合createFromAsset()设计的方式,步骤如下:

  1. 如果你的项目没有assets目录,在app/src/main下新建一个(目录结构:app/src/main/assets)
  2. 把res/raw里的cars_sample.json剪切到assets目录中
  3. 修改你的Database初始化代码,把路径改为文件名即可:
fun getInstance(context: Context): CarDatabase {
    if(instance == null) {
        instance = Room.databaseBuilder(
            context,
            CarDatabase::class.java,
            "cars_table"
        ).createFromAsset("cars_sample.json").build() // 这里直接用文件名
    }
    return instance as CarDatabase
}

解决方案2:保留文件在res/raw,手动读取并填充数据

如果不想移动文件,可以通过Room的回调机制,在数据库创建时手动读取raw目录的JSON并插入数据:

  1. 确保你的Dao层有批量插入的方法,比如:
@Dao
interface CarDao {
    @Insert
    fun insertAll(cars: List<Car>)
}
  1. 修改Database的初始化代码,添加addCallback:
fun getInstance(context: Context): CarDatabase {
    if(instance == null) {
        instance = Room.databaseBuilder(
            context,
            CarDatabase::class.java,
            "cars_table"
        ).addCallback(object : RoomDatabase.Callback() {
            override fun onCreate(db: SupportSQLiteDatabase) {
                super.onCreate(db)
                // 读取raw中的JSON文件
                val jsonContent = context.resources.openRawResource(R.raw.cars_sample)
                    .bufferedReader()
                    .use { it.readText() }
                
                // 解析JSON为实体列表(这里用Gson举例,你也可以用其他解析库)
                val carList = Gson().fromJson(jsonContent, Array<Car>::class.java).toList()
                
                // 开启子线程插入数据(不能在主线程操作数据库)
                Thread {
                    instance?.carDao()?.insertAll(carList)
                }.start()
            }
        }).build()
    }
    return instance as CarDatabase
}
  1. 如果用Gson解析,需要在app/build.gradle(Module级)添加依赖:
implementation 'com.google.code.gson:gson:2.10.1'

内容的提问来源于stack exchange,提问作者SNM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 14:02:42