JavaSpark-数据读存-CSV

来源:互联网 发布:windows下安装jdk7 编辑:程序博客网 时间:2024/06/07 03:31

CSV文件每行都有固定的数目的字段,记录通常一行一条 ,CSV原生并不支持嵌套字段,CSV中每条记录都没有字段名,所以常规做法是第一行中的每列作为字段名

  • 读取CSV
    读取CSV与JSON的读取方式一样,都是当做文本文件来读取数据,Java中使用的是opencsv库,
    如果你的CSV文件中刚好没有换行符,使用textFile()读取并解析数据
package spark_Function;import java.io.IOException;import java.io.StringReader;import org.apache.spark.SparkConf;import org.apache.spark.api.java.JavaRDD;import org.apache.spark.api.java.JavaSparkContext;import org.apache.spark.api.java.function.Function;import au.com.bytecode.opencsv.CSVReader;class CSV {    public static void main(String[] args) {        // TODO 自动生成的方法存根        SparkConf conf = new SparkConf().setMaster("local[2]").setAppName("SparkIO");        JavaSparkContext sc = new JavaSparkContext(conf);        JavaRDD<String> csvFile1 = sc.textFile("G:/sparkRS/CSV.csv");        JavaRDD<String[]> csvData = csvFile1.map(new ParseLine());        csvData.foreach(x->{                              for(String s : x){                                  System.out.println(s);                              }                           }                       );    }}class ParseLine implements Function<String,String[]>{    /**     *      */    private static final long serialVersionUID = 1L;    public String[] apply(String line) {        // TODO 自动生成的方法存根        CSVReader reader = new CSVReader(new StringReader(line));        String[] lineData = null;        try {            lineData = reader.readNext();        } catch (IOException e) {            // TODO 自动生成的 catch 块            e.printStackTrace();        }        return lineData;    }    @Override    public String[] call(String line) throws Exception {        // TODO 自动生成的方法存根        CSVReader reader = new CSVReader(new StringReader(line));        String[] lineData = null;        try {            lineData = reader.readNext();        } catch (IOException e) {            // TODO 自动生成的 catch 块            e.printStackTrace();        }        return lineData;    }}   #如果你的文件中有换行符,就需要读取整个文件,然后解析各段。文件很大时读取和解析过程就会很不辛的称为性能瓶颈#如果输入文件很小,可以使用wholeTextFile(),进行读取package spark_Function;import java.io.StringReader;import java.util.Iterator;import org.apache.spark.SparkConf;import org.apache.spark.api.java.JavaPairRDD;import org.apache.spark.api.java.JavaRDD;import org.apache.spark.api.java.JavaSparkContext;import org.apache.spark.api.java.function.FlatMapFunction;import au.com.bytecode.opencsv.CSVReader;import scala.Tuple2;class CSV {    public static void main(String[] args) {        // TODO 自动生成的方法存根        SparkConf conf = new SparkConf().setMaster("local[2]").setAppName("SparkIO");        JavaSparkContext sc = new JavaSparkContext(conf);        JavaPairRDD<String,String> csvData = sc.wholeTextFiles("G:/sparkRS/CSV.csv");        JavaRDD<String[]> keyRDD = csvData.flatMap(new ParseLine());        keyRDD.foreach(x -> {                            for(String s : x){                                System.out.println(s);            }});        sc.close();    }}class ParseLine implements FlatMapFunction<Tuple2<String,String>,String[]>{    /**     *      */    private static final long serialVersionUID = -274225435031841473L;    @Override    public Iterator<String[]> call(Tuple2<String, String> file) throws Exception {        // TODO 自动生成的方法存根        CSVReader reader = new CSVReader(new StringReader(file._2));        return reader.readAll().iterator();    }}##保存CSV#我们可以重用输出编码器来加速,在csv中我们不需要输出字段名,因此为了保持输出一致,需要闯将一种映射关系(做法是写一个函数,将各个字段转化为一定顺序的数组)#如果我们不知道输出的字段,那么我们可以遍历所有的数据,提取不同键,然后分别输出。package spark_Function;import java.io.IOException;import java.io.StringReader;import java.io.StringWriter;import org.apache.spark.SparkConf;import org.apache.spark.api.java.JavaRDD;import org.apache.spark.api.java.JavaSparkContext;import org.apache.spark.api.java.function.Function;import au.com.bytecode.opencsv.CSVReader;import au.com.bytecode.opencsv.CSVWriter;class CSV {    public static void main(String[] args) {        // TODO 自动生成的方法存根        SparkConf conf = new SparkConf().setMaster("local[2]").setAppName("SparkIO");        JavaSparkContext sc = new JavaSparkContext(conf);        JavaRDD<String> csvFile1 = sc.textFile("G:/sparkRS/CSV.csv");        JavaRDD<String[]> parsedData = csvFile1.map(new ParseLine());        parsedData = parsedData.filter(x->x[2].equals("怀旧专辑"));        parsedData.foreach(                            x->{                                long id = Thread.currentThread().getId();                                System.out.println("在线程 "+ id +" 中" + "打印当前数据元素:");                                for(String s : x){                                    System.out.print(s+ " ");                                }                                System.out.println();                            }                        );        parsedData.map(x->{             StringWriter stringWriter = new StringWriter();             CSVWriter csvWriter = new CSVWriter(stringWriter);             csvWriter.writeNext(x);             csvWriter.close();             return stringWriter.toString();        }).saveAsTextFile("G:/sparkRS/csv");        sc.close();    }}class ParseLine implements Function<String,String[]>{    /**     *      */    private static final long serialVersionUID = 1L;    public String[] apply(String line) {        // TODO 自动生成的方法存根        CSVReader reader = new CSVReader(new StringReader(line));        String[] lineData = null;        try {            lineData = reader.readNext();        } catch (IOException e) {            // TODO 自动生成的 catch 块            e.printStackTrace();        }        return lineData;    }    @Override    public String[] call(String line) throws Exception {        // TODO 自动生成的方法存根        CSVReader reader = new CSVReader(new StringReader(line));        String[] lineData = null;        try {            lineData = reader.readNext();        } catch (IOException e) {            // TODO 自动生成的 catch 块            e.printStackTrace();        }        return lineData;    }}   

“`