【问题标题】:Setting textinputformat.record.delimiter in sparksql在 sparksql 中设置 textinputformat.record.delimiter
【发布时间】:2017-12-28 05:40:53
【问题描述】:

在 spark2.0.1 ,hadoop2.6.0 中,我有很多文件用 '!@!\r' 分隔,而不是通常的换行 \n,例如:

=========================================

2001810086  rongq   2001    810!@!
2001810087  hauaa   2001    810!@!
2001820081  hello   2001    820!@!
2001820082  jaccy   2001    820!@!
2002810081  cindy   2002    810!@!

=========================================

我尝试根据Setting textinputformat.record.delimiter in spark提取数据 set textinputformat.record.delimiter='!@!\r';set textinputformat.record.delimiter='!@!\n';但仍然无法提取数据

在 spark-sql 中,我这样做: ===== =================================

create table ceshi(id int,name string, year string, major string)
row format delimited
fields terminated by '\t';

load data local inpath '/data.txt' overwrite into table ceshi;
select count(*) from ceshi;

结果是5,但我尝试set textinputformat.record.delimiter='!@!\r';然后select count(*) from ceshi;结果为1,分隔符不好用;

我还查看了hadoop2.6.0的源码,TextInputFormat.java中RecordReader的方法,我注意到默认的textinputformat.record.delimiter为null,然后LineReader.java使用readDefaultLine方法读取了一行终止CR、LF 或 CRLF(CR ='\r',LF ='\n')之一。

【问题讨论】:

    标签: hadoop apache-spark apache-spark-sql


    【解决方案1】:

    您应该使用sparkContexthadoopConfiguration api 将textinputformat.record.delimiter 设置为

    sc.hadoopConfiguration.set("textinputformat.record.delimiter", "!@!\r")
    

    那么如果你使用sparkContext作为读取文本文件

    sc.textFile("the input file path")
    

    你应该没事的。

    更新

    我注意到保存时带有分隔符\r 的文本文件更改为\n 分隔符。

    所以,下面的格式应该对你有用,就像对我一样

    sc.hadoopConfiguration.set("textinputformat.record.delimiter", "!@!\n")
    val data = sc.textFile("the input file path")
    val df = data.map(line => line.split("\t"))
    .map(array => ceshi(array(0).toInt, array(1), array(2), array(3)))
    .toDF
    

    需要一个名为ceshicase class,因为

    case class ceshi(id: Int, name: String, year: String, major :String)
    

    应该将数据框作为

    +----------+-----+-----+-----+
    |id        |name |year |major|
    +----------+-----+-----+-----+
    |2001810086|rongq| 2001|810  |
    |2001810087|hauaa| 2001|810  |
    |2001820081|hello| 2001|820  |
    |2001820082|jaccy| 2001|820  |
    |2002810081|cindy| 2002|810  |
    +----------+-----+-----+-----+
    

    现在你可以点击count函数

    import org.apache.spark.sql.functions._
    df.select(count("*")).show(false)
    

    输出为

    +--------+
    |count(1)|
    +--------+
    |5       |
    +--------+
    

    【讨论】:

    • ,您好,根据您的帮助,我尝试在spark-shell中设置参数,使用示例中的peopel.txt,但效果不好; scala> sc.hadoopConfiguration.set("textinputformat.record.delimiter", "!@!\r") scala> val sb = sc.textFile("file:///data/people.txt") sb: org. apache.spark.rdd.RDD[String] = file:///home/mr/ych/data/people.txt MapPartitionsRDD[1] at textFile at :24 scala> sb.first() res1: String = “迈克尔,29!@!安迪,30!@!贾斯汀,19!@!” scala> sb.count() res2: Long = 1
    猜你喜欢
    • 2013-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-08
    • 2018-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多