我正在使用一组相当大的txt文件,每个文件几个100MB。我想要做的是复制那些,我用函数MapFunc
映射每一行。请看下面我的第一次尝试非常慢。我很确定问题在于reduce函数,它连接了这个巨大的字符串。
将行写入outputFile
的顺序并不重要,但它们不能重叠。我已经看过Spark的saveAsTextFile
但据我所知,我无法指定文件名,只能指定目录,这对我的用例没用。另外,添加页眉和页脚以及RDD元素之间的逗号怎么样?如果能够将此应用程序调整到最佳性能,我将不胜感激。
val conf = new SparkConf().setAppName("MyApp")
val sc = new SparkContext(conf)
val input = sc.textFile(file)
val lines = input.filter(s => filterFunc(s)).map(s => MapFunc(s))
val output = lines.reduce((a, b) => a + ',' + b)
val outputFile = new File(outFile)
val writer = new BufferedWriter(new FileWriter(outputFile))
val buf = new StringBuilder
buf ++= "header"
buf ++= output
buf ++= "footer"
writer.append(buf)
writer.flush()
writer.close()
编辑:我的文件是简单的csv文件。他们可以有评论(#)。此外,我需要确保只处理包含3列的文件,因为允许用户提交自己的文件进行处理。这是由FilterFunc
完成的,说实话,它不会排除整个文件,只会排除与条件不匹配的行。一个简单的例子如下:
# File A
# generated mm/dd/yyyy
field11,field12,field13
field21,field22,field23
field31,field32,field33
输出填充如下所示:
$header
map(line1),
map(line2),
map(line3)
$footer
saveAsTextFile
非常接近我正在寻找的东西。但正如已经说过的那样,我可以控制输出文件的文件名和位置。
答案 0 :(得分:2)
您应该考虑直接写入文件,而不是使用临时缓冲区buf
。
val writer = new PrintWriter(new File(outFile))
writer.print("header")
writer.print(output)
writer.print("footer")
writer.flush()
writer.close()
您可以避免连接,也可以消耗buf
的内存。