如何使用 DataFrame API 和 SCALA 在 Spark 中读取固定长度的文件

How to read a fixed length file in Spark using DataFrame API and SCALA

我有一个固定长度的文件(下面显示了一个示例),我想使用 SCALA(不是 python 或 java)在 Spark 中使用 DataFrames API 读取此文件. 使用 DataFrames API 有读取文本文件、json 文件等的方法,但不确定是否有读取固定长度文件的方法。我在网上搜索这个并找到了一个 github link,但我必须为此目的下载 spark-fixedwidth-assembly-1.0.jar 但是我无法在任何地方找出罐子。我完全迷失在这里,需要你的建议和帮助。 Whosebug 中有几篇文章,但它们与 Scala 和 DataFrame 无关 API.

这是文件

56 apple     TRUE 0.56
45 pear      FALSE1.34
34 raspberry TRUE 2.43
34 plum      TRUE 1.31
53 cherry    TRUE 1.4 
23 orange    FALSE2.34
56 persimmon FALSE23.2

每列固定宽度为3,10,5,4

请提出您的意见。

嗯...使用子串来换行。然后 trim 删除空格。然后为所欲为。

case class DataUnit(s1: Int, s2: String, s3:Boolean, s4:Double)

sc.textFile('your_file_path')
  .map(l => (l.substring(0, 3).trim(), l.substring(3, 13).trim(), l.substring(13,18).trim(), l.substring(18,22).trim()))
  .map({ case (e1, e2, e3, e4) => DataUnit(e1.toInt, e2, e3.toBoolean, e4.toDouble) })
  .toDF

固定长度格式非常古老,我找不到适合这种格式的 Scala 库...所以我创建了自己的。

你可以在这里查看:https://github.com/atais/Fixed-Length

使用 Spark 非常简单,您将获得 DataSet 个对象!

您首先需要创建对象的描述,fe:

case class Employee(name: String, number: Option[Int], manager: Boolean)

object Employee {

    import com.github.atais.util.Read._
    import cats.implicits._
    import com.github.atais.util.Write._
    import Codec._

    implicit val employeeCodec: Codec[Employee] = {
      fixed[String](0, 10) <<:
        fixed[Option[Int]](10, 13, Alignment.Right) <<:
        fixed[Boolean](13, 18)
    }.as[Employee]
}

稍后只需使用解析器:

val input = sql.sparkContext.textFile(file)
               .filter(_.trim.nonEmpty)
               .map(Parser.decode[Employee])
               .flatMap {
                  case Right(x) => Some(x)
                  case Left(e) =>
                         System.err.println(s"Failed to process file $file, error: $e")
                         None
               }
sql.createDataset(input)