Scala中如何将Array[Array[Array[Double]]]导出到文件?
三维Double数组的持久化方案
针对你需要复用耗时计算出的Array[Array[Array[Double]]]的需求,这里提供几种靠谱的实现方式,替代字符串导出的混乱方案:
1. 原生对象序列化(最简单)
利用Java/Scala的对象序列化机制,直接把数组对象写入文件,读取时反序列化还原,代码极简:
导出代码
import java.io.{FileOutputStream, ObjectOutputStream} // 假设这是你耗时计算出的三维数组 val threeDArray: Array[Array[Array[Double]]] = Array( Array(Array(1.1, 1.2), Array(1.3, 1.4)), Array(Array(2.1, 2.2), Array(2.3, 2.4)) ) val outputStream = new ObjectOutputStream(new FileOutputStream("3d_array.ser")) outputStream.writeObject(threeDArray) outputStream.close()
导入代码
import java.io.{FileInputStream, ObjectInputStream} val inputStream = new ObjectInputStream(new FileInputStream("3d_array.ser")) val loadedArray = inputStream.readObject().asInstanceOf[Array[Array[Array[Double]]]] inputStream.close() // 验证结果 loadedArray.foreach(_.foreach(_.foreach(println)))
优缺点:
- 优点:零额外依赖,代码几行搞定,完全还原原数组结构
- 缺点:生成的
.ser文件是二进制不可读,且Scala/JVM版本变化可能导致反序列化失败
2. JSON序列化(可读+跨语言)
用JSON库把数组转成结构化的JSON字符串,文件可读,还能被其他语言解析,推荐用Circe(Scala生态常用的JSON库):
先添加依赖(SBT示例)
libraryDependencies ++= Seq( "io.circe" %% "circe-core" % "0.14.6", "io.circe" %% "circe-generic" % "0.14.6", "io.circe" %% "circe-parser" % "0.14.6" )
导出代码
import io.circe.generic.auto._ import io.circe.syntax._ import java.io.PrintWriter val threeDArray: Array[Array[Array[Double]]] = // 你的三维数组 val jsonString = threeDArray.asJson.noSpaces // 紧凑格式,也可以用prettyPrint()生成格式化的JSON new PrintWriter("3d_array.json") { write(jsonString) close() }
导入代码
import io.circe.parser.decode import scala.io.Source val jsonContent = Source.fromFile("3d_array.json").mkString val loadedArray = decode[Array[Array[Array[Double]]]](jsonContent) match { case Right(data) => data case Left(error) => throw new RuntimeException(s"解析失败: ${error.getMessage}") }
优缺点:
- 优点:JSON文件可读,跨语言兼容,结构清晰
- 缺点:序列化/反序列化速度比二进制慢,文件体积更大,适合数据量中等的场景
3. 自定义二进制格式(最高性能)
如果你的数组数据量极大,追求最快的读写速度和最小的文件体积,可以手动写入二进制数据,严格按维度长度+数值的顺序存储:
导出代码
import java.io.{DataOutputStream, FileOutputStream} val threeDArray: Array[Array[Array[Double]]] = // 你的三维数组 val outputStream = new DataOutputStream(new FileOutputStream("3d_array.bin")) // 依次写入三个维度的长度,再写入每个Double值 outputStream.writeInt(threeDArray.length) threeDArray.foreach(secondDim => { outputStream.writeInt(secondDim.length) secondDim.foreach(thirdDim => { outputStream.writeInt(thirdDim.length) thirdDim.foreach(outputStream.writeDouble) }) }) outputStream.close()
导入代码
import java.io.{DataInputStream, FileInputStream} val inputStream = new DataInputStream(new FileInputStream("3d_array.bin")) val firstDimLen = inputStream.readInt() val loadedArray = Array.fill(firstDimLen) { val secondDimLen = inputStream.readInt() Array.fill(secondDimLen) { val thirdDimLen = inputStream.readInt() Array.fill(thirdDimLen)(inputStream.readDouble()) } } inputStream.close()
优缺点:
- 优点:读写速度最快,文件体积最小,完全可控
- 缺点:文件不可读,需要严格遵循写入格式,出错后难以排查,适合性能优先的场景
内容的提问来源于stack exchange,提问作者Hulmi
相关产品推荐
相关产品推荐

