如何在hadoop hdfs中列出目录及其子目录中的所有文件

nik*_*686 20 java hadoop hdfs

我在hdfs中有一个文件夹,它有两个子文件夹,每个子文件夹有大约30个子文件夹,最后每个子文件夹包含xml文件.我想列出所有只提供主文件夹路径的xml文件.在本地我可以使用apache commons-io的 FileUtils.listFiles()来做到这一点.我试过这个

FileStatus[] status = fs.listStatus( new Path( args[ 0 ] ) );
Run Code Online (Sandbox Code Playgroud)

但它只列出了两个第一个子文件夹,并没有更进一步.在hadoop有没有办法做到这一点?

Pra*_*shi 30

如果您使用的是hadoop 2.*API,那么有更优雅的解决方案:

    Configuration conf = getConf();
    Job job = Job.getInstance(conf);
    FileSystem fs = FileSystem.get(conf);

    //the second boolean parameter here sets the recursion to true
    RemoteIterator<LocatedFileStatus> fileStatusListIterator = fs.listFiles(
            new Path("path/to/lib"), true);
    while(fileStatusListIterator.hasNext()){
        LocatedFileStatus fileStatus = fileStatusListIterator.next();
        //do stuff with the file like ...
        job.addFileToClassPath(fileStatus.getPath());
    }
Run Code Online (Sandbox Code Playgroud)

  • getConf() 方法是什么? (2认同)

Chr*_*ite 18

您需要使用FileSystem对象并对生成的FileStatus对象执行一些逻辑,以手动递归到子目录中.

您还可以应用PathFilter仅使用listStatus(Path,PathFilter)方法返回xml文件

hadoop FsShell类为hadoop fs -lsr命令提供了这样的示例,这是一个递归ls - 参见源代码,在第590行附近(递归步骤在第635行触发)

  • 破坏的参考链接 (3认同)

ali*_*der 13

你试过这个:

import java.io.*;
import java.util.*;
import java.net.*;
import org.apache.hadoop.fs.*;
import org.apache.hadoop.conf.*;
import org.apache.hadoop.io.*;
import org.apache.hadoop.mapred.*;
import org.apache.hadoop.util.*;

public class cat{
    public static void main (String [] args) throws Exception{
        try{
            FileSystem fs = FileSystem.get(new Configuration());
            FileStatus[] status = fs.listStatus(new Path("hdfs://test.com:9000/user/test/in"));  // you need to pass in your hdfs path

            for (int i=0;i<status.length;i++){
                BufferedReader br=new BufferedReader(new InputStreamReader(fs.open(status[i].getPath())));
                String line;
                line=br.readLine();
                while (line != null){
                    System.out.println(line);
                    line=br.readLine();
                }
            }
        }catch(Exception e){
            System.out.println("File not found");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


小智 12

/**
 * @param filePath
 * @param fs
 * @return list of absolute file path present in given path
 * @throws FileNotFoundException
 * @throws IOException
 */
public static List<String> getAllFilePath(Path filePath, FileSystem fs) throws FileNotFoundException, IOException {
    List<String> fileList = new ArrayList<String>();
    FileStatus[] fileStatus = fs.listStatus(filePath);
    for (FileStatus fileStat : fileStatus) {
        if (fileStat.isDirectory()) {
            fileList.addAll(getAllFilePath(fileStat.getPath(), fs));
        } else {
            fileList.add(fileStat.getPath().toString());
        }
    }
    return fileList;
}
Run Code Online (Sandbox Code Playgroud)

快速示例:假设您具有以下文件结构:

a  ->  b
   ->  c  -> d
          -> e 
   ->  d  -> f
Run Code Online (Sandbox Code Playgroud)

使用上面的代码,您将获得:

a/b
a/c/d
a/c/e
a/d/f
Run Code Online (Sandbox Code Playgroud)

如果只想要叶子(即fileNames),请在else块中使用以下代码:

 ...
    } else {
        String fileName = fileStat.getPath().toString(); 
        fileList.add(fileName.substring(fileName.lastIndexOf("/") + 1));
    }
Run Code Online (Sandbox Code Playgroud)

这将给出:

b
d
e
f
Run Code Online (Sandbox Code Playgroud)