我在HDFS中有一个名为file1的文件,其中包含以下行:(每行是一个目录路径)
this/is/path1
this/is/path2
this/is/path3
.
.
.
this/is/path1000ormore
我有一个Scala Spark功能如下:
val resultset=sc.hadoopFile(inputpath,classOf[TextInputFormat],classOf[LongWritable],classOf[Text]).flatMap {
case (k, v) => if (k.get == 0) Seq(v.toString) else Seq.empty[String]
}
我想传递来自" file1"的每一行。代替"输入路径" (必须是一个String)在hadoopFile函数中,并获得每个迭代/循环的结果。 我怎么能这样做?
额外信息:
函数实际执行的操作:上面的函数从指定的目录路径获取第一个文件,而不是" inputpath"并给出文件的第一行。我想对存储在" file1"中的所有目录路径执行此操作,因此我正在寻找有关如何在循环/迭代中执行此操作的解决方案。
更新 我试着将它放在这样的循环中:
val lines=Source.fromFile("/path/to/file1.txt").getLines.toList
for(i<-lines){
val firstLines=sc.hadoopFile(i,classOf[TextInputFormat],classOf[LongWritable],classOf[Text]).flatMap {
case (k, v) => if (k.get == 0) Seq(v.toString) else Seq.empty[String]
}
这大约持续了10分钟(file1包含大约34,000行)并且没有导致任何错误。但是当我尝试使用以下命令查看输出的几行时,
firstLines.take(3)
我收到错误说:
error: not found: value firstLines
firstLines
^
所以我不认为循环成功运行,因此firstLines永远不会被创建,尽管我不知道问题是什么。有人可以提供解决方案吗?
答案 0 :(得分:1)
可以分两步完成:
另外2)可以改进:1)中的所有项目都可以用逗号连接在一个字符串中,字符串作为“inputpath”参数传递。您将拥有一个包含所有文件数据的RDD。可以应用过滤器“k.get == 0”来获得最终结果。
首先可以这样实现:
val lines = Source.fromFile("file1.txt").getLines.toSeq.view
val resultDF = lines.map(current =>
sc.hadoopFile(current, classOf[TextInputFormat], classOf[LongWritable], classOf[Text]).filter(_._1 == 0)
).reduce(_ union _)
resultDF.take(3).foreach(println)