public static List<FileStatus> getFileStatusRecurse(Path base, FileSystem fs) {
    try {
      List<FileStatus> results = new ArrayList<>();
      if (isS3a(fs)) {
        // S3A file system has an optimized recursive directory listing implementation however it doesn't support filtering.
        // Therefore we filter the result set afterwards. This might be not so optimal in HDFS case (which does a tree walking) where a filter could have been used.
        listS3FilesRecursive(base, fs, results);
      } else {
        listStatusRecursively(fs, fs.getFileStatus(base), results);
      }
      return results;
    } catch (IOException e) {
      // globStatus() API returns empty FileStatus[] when the specified path
      // does not exist. But getFileStatus() throw IOException. To mimic the
      // similar behavior we will return empty array on exception. For external
      // tables, the path of the table will not exists during table creation
      return Collections.emptyList();
    }
  }
Get all file status from a root path and recursively go deep into certain levels.

@param base
         the root path
@param fs
         the file system
@return array of FileStatus
standalone-metastore/metastore-common/src/main/java/org/apache/hadoop/hive/metastore/utils/FileUtils.java