簡體   English   中英

在spark java api中以遞歸方式讀取HDFS中的所有文件

[英]reading all files from HDFS recursively in spark java api

我正在使用spark從目錄中的單個RDD中讀取HDFS中所有文件的數據,並且它也是子目錄。 我找不到任何有效的方法來做到這一點。 所以我嘗試編寫一些自定義代碼,如下所示:

public Object fetch(String source,String sink) {

    //reading data
    boolean isDir=new File(source).isDirectory();
    System.out.println("isDir="+isDir);
    JavaRDD<String> lines;
    if(isDir)
    {

        lines=readFiles(new File(source).listFiles(), null);
    }
    else
        lines= sc.textFile(source);

    lines.saveAsTextFile(sink);
    return true;
}

public static JavaRDD<String> readFiles(File[] files,JavaRDD<String> lines) {
    for (File file : files) {
        if (file.isDirectory()) {
            readFiles(file.listFiles(),lines); // Calls same method again.
        } 
        else {
            if(lines==null)
                lines=sc.textFile(file.getPath());
            else
            {
                JavaRDD<String> r=sc.textFile(file.getPath());
                lines.union(r);
            }
        }
    }
    return lines;
}

但這不是我預期的工作,因為isDir包含錯誤,告訴它不是一個目錄。 請問你能指導我什么是錯的? 有沒有一種有效的方法來完成這項工作? 非常感謝

由於spark可以基於Hadoop作業配置讀取數據,因此可以使用FileInputFormat#setInputDirRecursive方法。

JavaSparkContext context = new JavaSparkContext();

Job job;

try {
  job = Job.getInstance();
  FileInputFormat.setInputPaths(job, new Path("/path/to/input/directory));
  FileInputFormat.setInputDirRecursive(job, true);
} catch (IOException e1) {
  e1.printStackTrace();
  System.exit(1);
}

JavaRDD<Text> sourceData = context.newAPIHadoopRDD(job.getConfiguration(), TextInputFormat.class, LongWritable.class, Text.class)
  .values();

顯然,您最終將使用Text數據類型而不是String。

“*”字符以遞歸方式讀取文件夾

JavaSparkContext sc = new JavaSparkContext(conf);
sc.textFile("/my/directory/*");

閱讀此鏈接了解更多信息:

http://spark.apache.org/docs/latest/programming-guide.html#external-datasets

所以最后我找到了解決方案。 我錯了,因為我使用的是File對象,用於從本地文件系統讀取文件。 為了讀/寫HDFS,我們需要使用org.apache.hadoop.fs。*

所以這是解決方案

public Object fetch(String source,String sink) {

    //reading data
    Path src=new Path(source);
    try {
        if(fs.exists(src))
        {
            FileStatus[] lists=fs.listStatus(src);
            readFiles(lists);
        }
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return true;
}

public void readFiles(FileStatus[] files) {
        for(int i=0;i<files.length;i++)
        {
            if(files[i].isDirectory())
            {
                try {
                    readFiles(fs.listStatus(files[i].getPath()));
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            else
            {
                    if(lines==null)
                    {
                       Path p=files[i].getPath();
                       JavaRDD<String> lines=sc.textFile(p.toString());
                    }
                    else
                   {
                      JavaRDD<String> r=sc.textFile(file.getPath());
                      lines.union(r);
                   }
        }
  }
  return lines;
 }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM