使用Java和Spark将本地映像中的序列文件写入HDFS

时间:2016-06-24 14:53:48

标签: java hadoop apache-spark hdfs spark-streaming

正如标题所说,这是我的目标。

  • 我需要从目录中加载一堆非文本文件
  • 从中提取常用文件信息(创建日期,作者,类型......那些)
  • 创建
  • 类型的序列文件
  • 将新提取的信息放入.seq文件的密钥
  • 将所有这些内容存储在hdfs目录中。

我使用spark的原因是为了可扩展性(要处理数千个文件,我将有一组工作人员可用),因为我想在图像目录上实现SParkStreaming接收器,所以文件将自动处理。 这是我的初始代码:

JavaPairRDD<String, String> imageRDD = jsc.wholeTextFiles("file:///home/cloudera/Pictures/");

    imageRDD.mapToPair(new PairFunction<Tuple2<String,String>, Text, Text>() {

        @Override
        public Tuple2<Text, Text> call(Tuple2<String, String> arg0)
                throws Exception {
            return new Tuple2<Text, Text>(new Text(arg0._1),new Text(arg0._2));
        }

    }).saveAsNewAPIHadoopFile("hdfs://localhost:8020/user/hdfs/sparkling/try.seq", Text.class, Text.class, SequenceFileOutputFormat.class);

这里我将图像作为文本文件加载,并使用hadoop库中的Text类型创建一个元组。这有效,但是:

  1. 该文件不会保存为单个文件,而是保存为包含分区的文件夹。
  2. 它不是一个字节数组,而是文件的文本表示形式。我们都知道如何唠叨从文本到图像(或其他任何东西)的重新转换
  3. 如果我加载这样的文件,是否有办法提取所需的信息?
  4. 我已尝试将文件加载为sparkContext.binaryFiles(<directory>),但我总是丢失了如何提取信息以及如何保存信息。
    我似乎无法在互联网上找到答案:你们中有谁对此有所了解吗?

1 个答案:

答案 0 :(得分:1)

我是这样做的:

JavaPairRDD<String, PortableDataStream> imageByteRDD = jsc.binaryFiles(SOURCE_PATH);
        if(!imageByteRDD.isEmpty())
            imageByteRDD.foreachPartition(new VoidFunction<Iterator<Tuple2<String,PortableDataStream>>>() {

            @Override
            public void call(
                    Iterator<Tuple2<String, PortableDataStream>> arg0)
                    throws Exception {
                Configuration conf = new Configuration();
                conf.set("fs.defaultFS", HDFS_PATH);
                while(arg0.hasNext()){
                    Tuple2<String,PortableDataStream>fileTuple = arg0.next();
                    Text key = new Text(fileTuple._1());
                    String fileName = key.toString().split(SEP_PATH)[key.toString().split(SEP_PATH).length-1].split(DOT_REGEX)[0];
                    String fileExtension = fileName.split(DOT_REGEX)[fileName.split(DOT_REGEX).length-1];

                      BytesWritable value = new BytesWritable( fileTuple._2().toArray());
                         SequenceFile.Writer writer = SequenceFile.createWriter(
                                 conf, 
                                 SequenceFile.Writer.file(new Path(DEST_PATH + fileName + SEP_KEY + getCurrentTimeStamp()+DOT+fileExtension)),
                               SequenceFile.Writer.compression(SequenceFile.CompressionType.RECORD, new BZip2Codec()),
                               SequenceFile.Writer.keyClass(Text.class), SequenceFile.Writer.valueClass(BytesWritable.class));
                         key = new Text(key.toString().split(SEP_PATH)[key.toString().split(SEP_PATH).length-2] + SEP_KEY + fileName + SEP_KEY + fileExtension);
                            writer.append(key, value);
                         IOUtils.closeStream(writer);

                }
            }
        });