Java 如何根据dataframeWriter中的可用选项操作存储在hdfs中的csv文件头?

Java 如何根据dataframeWriter中的可用选项操作存储在hdfs中的csv文件头?,java,csv,hadoop,apache-spark,apache-spark-2.0,Java,Csv,Hadoop,Apache Spark,Apache Spark 2.0,我有一个将数据集写入hdfs中某个位置的功能。我注意到,如果数据集是union或join功能的结果,那么hdfs中会创建多个部分。该地点的内容如下:- _成功 零件-00000-7908d1be-5409-4ac4-a218-29b9b1f99449 零件-00001-7908d1be-5409-4ac4-a218-29b9b1f99449 如果“dataset”是存储在hdfs中位置“locale”处的数据集,则dataframeWriter csv选项(标头、sep、限定符)存储在“opti

我有一个将数据集写入hdfs中某个位置的功能。我注意到,如果数据集是union或join功能的结果,那么hdfs中会创建多个部分。该地点的内容如下:-

  • _成功
  • 零件-00000-7908d1be-5409-4ac4-a218-29b9b1f99449
  • 零件-00001-7908d1be-5409-4ac4-a218-29b9b1f99449
  • 如果“dataset”是存储在hdfs中位置“locale”处的数据集,则dataframeWriter csv选项(标头、sep、限定符)存储在“options”(标头始终为true)中,如下所示:-

      DataFrameWriter dataFrameWriter = dataset.write();
      if(options != null && !options.isEmpty()) {
                    dataFrameWriter = dataFrameWriter.options(options);
                }
                dataFrameWriter.mode(saveMode).csv(locale);
    
    然后使用fileUtil“copyMerge”将其合并为单个部分:-

    CopyMerge()是一个函数,它获取位置的所有内容并合并它们,然后将它们写入提供的目标路径

    我在每个区块中面临的问题是写入标头,通过copyMerge,标头会重复多次:-

        Header1,Header2,Header3
        x,y,z
        a,b,c
        Header1,Header2,Header3
        r,t,y
        h,y,d
    
    我试图通过将“header”选项设为false并使用outputStream将header作为字符串写入同一位置,然后调用copyMerge来解决这个问题,如前所述

     String separator = (StringUtils.isNotEmpty(options.get(SEPARATOR)))? 
      options.get(SEPARATOR):",";
        String header = String.join(separator,dataset.columns());
        header = header+'\n';
    
     InputStream stream = new 
               ByteArrayInputStream(header.getBytes(StandardCharsets.UTF_8));
    
     writeFile(location + "/header", stream); //this being another function that writes the stream into the location
    
    这种方法面临的问题是,我必须为所有csv选项(如“escapeQuotes”、“quoteAll”等)操作标题,就像我为分隔符操作标题一样


    是否有任何方法可以处理此标题问题,而不必以不同方式操作标题。

    是否有特定原因使您希望将其放在单个文件中?您始终可以在数据集上调用
    coalesce(1)
    ,这将把所有内容放在一个分区中,并将其存储在一个文件中。但是,这要求您的数据集足够小,以便所有内容都可以放入一个分区。场景是:-我必须将任何操作的结果(以数据集的形式)存储到csv文件中。如果需要,这个文件可以在以后下载或使用。是的,我从你的问题中得到了这个答案,但我再次问——为什么把它放在一个文件中很重要?Spark把它写了几个部分——为什么不保持这样呢?问题不是合并。问题是,如果header为true,则创建的每个部分最终都有一个header,因此即使我打开一个InputStream并读取该文件,该header也会重复。除了第一部分(part_00000..)之外,我是否可以跳过所有其他部分的标题写入。哦,我明白了-您正在使用其他非spark应用程序读取文件。好吧,那么好吧,你只能选择不指定任何标题——或者像我在评论中写的那样,将所有内容放在一个文件中。
     String separator = (StringUtils.isNotEmpty(options.get(SEPARATOR)))? 
      options.get(SEPARATOR):",";
        String header = String.join(separator,dataset.columns());
        header = header+'\n';
    
     InputStream stream = new 
               ByteArrayInputStream(header.getBytes(StandardCharsets.UTF_8));
    
     writeFile(location + "/header", stream); //this being another function that writes the stream into the location