在Apache Spark中读取具有多个部分标题且具有可变部分内容的文件

时间:2018-10-08 09:01:38

标签: java scala csv apache-spark

是否可以使用Spark API读取 CSV文件,该文件包含具有不同标题的多个部分?文件的结构如下

BatchCode#1
Name,Surname,Address
AA1,BBB,CCC
AA2,BBB,CCC
AA3,BBB,CCC

BatchCode#2
Name,Surname,Address,Phone
XY1,BBB,CCC,DDD
XY2,BBB,CCC,DDD
XY3,BBB,CCC,DDD

在读取记录时,我们需要注意标头以及各节之间的文件格式可能不同。 BatchCode信息需要从标题中提取,并且应该是该节中每个记录的一部分-例如,第1行的数据应解析为:

Name: AAA1
Surname: BBB
Address:CCC
BatchCode:1

我想到以下选项,但我不确定是否会造成重大问题:

  1. 使用WholeTextFile读取文件。这将使用单个线程读取文件,但它将整个文件加载到内存中,并且可能导致大文件出现内存问题。
  2. 使用sc.textFile上的coalesce(1)强制Spark在单个线程中读取文件。我不确定订单是否总是可以保证的。一旦将文件获取为RDD,我们将在读取文件时缓存标题行并将其与相应的数据记录合并。

即使以上方法可行,它们是否有效?什么是最有效的方法?

2 个答案:

答案 0 :(得分:0)

我只为复杂的用例编写了Scala程序,从而保证了顺序性。否则太难了。如果首先从xls或xlsx发出文件,则通过csvkit处理文件。

答案 1 :(得分:0)

以下程序对我有用:

JavaPairRDD<String, PortableDataStream> binaryFiles = sc.binaryFiles(file);

PortableRecordReader reader = new PortableRecordReader();
JavaPairRDD<String, Record> fileAndLines = binaryFiles.flatMapValues(reader);

PortableRecordReader在其中打开DataInputStream并将其转换为InputStreamReader,然后使用CSV解析器将这些行转换为Record对象中的预期输出,并合并标头。