有没有一种方法可以在Spark(带有Scala)中通过自定义分隔符拆分,而不是逐行读取,以读取一组键,值对?

时间:2019-01-26 00:21:31

标签: scala apache-spark apache-spark-sql

我有一个格式的输入.txt文件。

Record  
ID||1  
Word||ABC   
Language||English   
Count||2   
Record  
ID||2  
Word||DEF  
Language||French  
Count||4 

,依此类推。

我是Apache Spark / Scala的新手。

我看到有一些选项可以通过使用.textFile方法逐行读取文件,或者通过.wholeTextFile方法读取整个文件。我们还可以读取CSV格式的文件。

但是,假设我想读取这样的文件并从中创建一个case类,其中将包含成员id,单词,语言,数量,我该如何处理?

1 个答案:

答案 0 :(得分:0)

假设您的输入格式是一致的(没有随机的空格,总是以“ Record \ n”结尾),那么下面的代码可以正常工作。

密钥在hadoop配置的"textinputformat.record.delimiter"

case class Foo(ID : Long, Word : String, Language : String, Count : Long)

val conf = new SparkConf()
conf.setMaster("local[*]")
conf.setAppName("stackOverflow")
val sc = new SparkContext(conf)

sc.hadoopConfiguration.set("textinputformat.record.delimiter","Record\n")

val rdd = sc.textFile("C:\\TEMP\\stack.txt")
  .flatMap(record => {
    if (record.isEmpty) None //needed to remove first empty string delimited by "Record\n"
    else {
      val lines = record.split("\n").map(_.split("\\|\\|"))
      //lines.foreach(x=>println(x.mkString(",")))
      Some(Foo(
        lines(0)(1).toLong,
        lines(1)(1),
        lines(2)(1),
        lines(3)(1).toLong
      ))
    }
  })
rdd.foreach(println)

输出为

Foo(2,DEF,French,4)
Foo(1,ABC,English,2)