一、使用反射的方式
这种方式是使用反射的方式,用反射去推倒出来RDD里面的schema,也就是根据包括case class数据的RDD转换成DataFrame,这个方式简单,在已知schema的时候非常方便
def main(args: Array[String]): Unit = {
val spark = SparkSession.builder().appName("TopNStatJob")
.config("spark.sql.sources.partitionColumnTypeInference.enabled","false")
.master("local[2]").getOrCreate()
// val accessRdd = spark.sparkContext.textFile("D://item//mukewang//data//1.txt")
val accessRdd = transfer(spark,"D://item//mukewang//data//province.txt")
inferReflection(accessRdd,spark)
}
def inferReflection(rdd :RDD[String],spark:SparkSession): Unit = {
// val rdd1 = rdd.map(line =>{
// val splits = line.split("\t")
//
// })
//注意:需要导入隐式转换
import spark.implicits._
val rddDF = rdd.map(_.split("\t")).map(line => region(line(0),line(1))).toDF()
rddDF.show()
}
case class region(code: String, name: String)
二、使用编程方式动态转
首先构建一个RDD,再创建由一个 StructType 表示的模式,构造schema用到了两个类StructType和StructFile,然后通过 createDataFrame 方法应用模式
def program(rdd :RDD[String],spark:SparkSession):Unit={
// rdd.take(10).foreach(println)
val rddDF = rdd.map(_.split("\t")).map(line => Row(line(0),line(1)))
val structType = StructType(Array(StructField("code",StringType,true),
StructField("name",StringType,true)
))
val infoDF = spark.createDataFrame(rddDF,structType)
infoDF.printSchema()
infoDF.show()
}
三、txt文件中文乱码
下面是一个读取txt文件中文乱码的解决方法:
def transfer(sc:SparkSession,path:String):RDD[String]={
sc.sparkContext.hadoopFile(path,classOf[TextInputFormat],classOf[LongWritable],classOf[Text],1)
.map(p => new String(p._2.getBytes, 0, p._2.getLength, "GBK"))
}
在使用时直接调用即可:
val accessRdd = transfer(spark,"D://item//mukewang//data//province.txt")