본문 바로가기

OpenSource/Spark

[Spark] HDFS 하위 경로의 모든 파일 읽기(with Java)

동일한 Level에 파일이 있는 경우 경로에 ***.parquet 을 사용하면 모든 파일을 쉽게 읽을수 있다.

예를 들면 hdfs의 경로가 아래와 같다면

/test/2020-04-25/1.parquet
                /2.parquet
     /2020-04-26/1.parquet
                /2.parquet

test 디렉토리 하위의 parquet 파일을 읽으려면

Dataset<Row> dataSet = sparkSession.read().parquet("/test/**/*.parquet")

처럼 읽을 수 있다.

하지만 아래와 같이 파일의 depth가 다른경우 ** 로는 하위 모든 파일을 읽을 수 없다.

/test/order/2020/04/25/1.parquet
                      /2.parquet
      /product/2020-04-25/1.parquet
                         /2.parquet

이럴때는 Hadoop-Client를 이용하여 특정 디렉토리 하위의 모든 파일을 읽어 들이는 방법을 사용해야 한다.

import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.LocatedFileStatus;
import org.apache.hadoop.fs.RemoteIterator;

FileSystem fs = FileSystem.get(new Configuration());
RemoteIterator<LocatedFileStatus> files = fs.listFiles(new Path("/test") , true);
List<String> filePaths = new ArrayList<>();

while(files.hasNext()) {
    LocatedFileStatus file = files.next();
    String filePath = file.getPath().toString();
    if(filePath.endsWith(".parquet")) {
        filePaths.add(filePath);
    }
}

Dataset<Row> dataSet = sparkSession.read().parquet(filePaths.toArray(new String[filePaths.size()]))

위의 방식으로 특정 디렉토리(/test) 하위의 모든 파일&디렉토리를 탐색하며 List에 담고 이를 sparkSession.read().parquet()에 Array 형태로 넘겨주면된다.