Scala 2.12.8(IntelliJ环境下)JSON文件读取与解析问题
问题解决与JSON解析指导
一、os-lib 报错 "not found: value os" 的解决办法
1. 补全导入语句
你漏了os-lib的核心导入,必须在代码最开头加上这两行:
import os._ import ujson._
os-lib的所有API都封装在os._包里,没导入的话IDE肯定找不到os对象。
2. 修复IntelliJ依赖加载问题
如果加了导入还是报错,大概率是IDE没同步sbt依赖:
- 点击右侧sbt面板的Refresh all sbt projects按钮,强制重新拉取依赖。
- 要是还不行,直接清缓存重启:File > Invalidate Caches... > 选择Invalidate and Restart,这招能解决大部分IDE缓存导致的依赖找不到问题。
3. 调整依赖版本(可选)
你用的upickle 3.0.0-M2是预览版,和os-lib 0.9.0可能存在兼容性问题,换成稳定版更稳妥:
libraryDependencies += "com.lihaoyi" %% "os-lib" % "0.8.1" libraryDependencies += "com.lihaoyi" %% "upickle" % "2.0.0"
二、Spark DataFrame 访问嵌套字段的具体方法
假设你的JSON结构是这种嵌套格式:
{ "user": { "name": "Alice", "age": 30 }, "orders": [{"id": 1, "amount": 100}] }
1. 直接读取嵌套字段
- 用点符号快速选择:
// 选择单个嵌套字段 df.select("user.name", "user.age").show(false) // 读取数组内的嵌套字段 df.select("orders.id").show(false)
- 用
col+getItem的灵活方式:
import org.apache.spark.sql.functions.col df.select(col("user").getItem("name").alias("user_name")).show(false)
2. 把嵌套字段展开成顶层列
如果想把嵌套结构体全部展开到顶层,用select配合*:
df.select("user.*", "orders.*").show(false)
3. 处理数组类型的嵌套字段
如果嵌套字段是数组,用explode把数组拆成多行:
import org.apache.spark.sql.functions.explode df.withColumn("order", explode(col("orders"))) .select("user.name", "order.id", "order.amount") .show(false)
三、os-lib + upickle 解析JSON的完整示例
补全导入后的可运行代码:
import os._ import ujson._ object JsonParser { def main(args: Array[String]): Unit = { // 读取JSON文件 val jsonString = os.read(os.pwd / "src" / "main" / "scala" / "config.json") // 解析JSON val data = ujson.read(jsonString) // 访问嵌套字段(根据你的JSON结构调整路径) val childValue = data("parent")("child").str println(childValue) // 如果是数组嵌套,按索引取元素 val firstArrayItem = data("arrayField")(0).num println(firstArrayItem) } }
四、其他可选的JSON解析方案
1. 用Scala标准库(零依赖)
适合简单场景,无需添加任何额外依赖:
import scala.io.Source import scala.util.parsing.json.JSON object StdLibJsonParser { def main(args: Array[String]): Unit = { val jsonString = Source.fromFile("src/main/scala/config.json").mkString val jsonOpt = JSON.parseFull(jsonString) jsonOpt match { case Some(map: Map[String, Any]) => // 逐层访问嵌套字段 val userMap = map("user").asInstanceOf[Map[String, Any]] println(userMap("name")) case _ => println("JSON解析失败") } } }
2. 用Circe(Scala生态流行的函数式JSON库)
先在build.sbt添加依赖:
libraryDependencies += "io.circe" %% "circe-core" % "0.14.6" libraryDependencies += "io.circe" %% "circe-parser" % "0.14.6"
然后编写解析代码:
import io.circe._ import io.circe.parser._ import scala.io.Source object CirceParser { def main(args: Array[String]): Unit = { val jsonString = Source.fromFile("src/main/scala/config.json").mkString val parseResult = parse(jsonString) parseResult match { case Right(json) => // 直接通过路径获取嵌套字段 val name = json.hcursor.get[String]("user.name") println(name) case Left(error) => println(s"解析出错: ${error.getMessage}") } } }
内容的提问来源于stack exchange,提问作者M_Gh
相关产品推荐
相关产品推荐

