본문 바로가기

Hadoop

[Hadoop] 여러 파일들을 하나의 압축파일로 만들기

단순 Java로 로컬 디스크에 Zip파일 만드는 버전

- http://seongtak-yoon.tistory.com/74



목적

- 여러 디렉토리에 있는 spark로 partition된 파일들을 hadoop 파일 시스템을 통해 읽은 후 하나의 zip파일로 만들기



@Test
public void testRead다른디렉토리HdfsFilesToOneZipFile() throws Exception {
String hdfs = PropertyUtils.getValue("hdfs.url"); // hdfs://sample:port

// 읽을 디렉토리 및 zip에 저장할 파일명 정보
Map<String, String> fooSaveInfoMap = new HashMap<>();
fooSaveInfoMap.put("path", "/sample/foo");
fooSaveInfoMap.put("filename", "foo.csv");

Map<String, String> barSaveInfoMap = new HashMap<>();
barSaveInfoMap.put("path", "/sample/bar");
barSaveInfoMap.put("filename", "bar.csv");

List<Map<String, String>> paths = Arrays.asList(fooSaveInfoMap, barSaveInfoMap);
String outputPath = inputPrefixPath + "/all/file.zip";

// hdfs config
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(new URI(hdfs), conf);

// zip output (하둡이 아닌 로컬 디스크에 저장하실려면 FileOutputStream 사용하면 됩니다)
FSDataOutputStream zipHdfsFileOutputStream = fs.create(new Path(outputPath));
ZipOutputStream zipOutputStream = new ZipOutputStream(zipHdfsFileOutputStream);

// 디렉토리 loop
for (Map<String, String> path : paths) {
FileStatus[] statuses = fs.listStatus(new Path(path.get("path")));

InputStream in = null;
ByteArrayOutputStream out = new ByteArrayOutputStream();

// 파일 loop
for (FileStatus status: statuses) {
in = fs.open(status.getPath());
IOUtils.copyBytes(in, out, conf, false);
}

ZipEntry zipEntry = new ZipEntry(path.get("filename")); // 내부 파일명
zipOutputStream.putNextEntry(zipEntry);
zipOutputStream.write("\ufeff".getBytes()); // csv bom 추가
zipOutputStream.write(out.toByteArray());

// close
IOUtils.closeStream(in);
IOUtils.closeStream(out);
}

// zip stream close
IOUtils.closeStream(zipOutputStream);
IOUtils.closeStream(zipHdfsFileOutputStream);
}



하둡, 스파크에서 제공해주는 라이브러리 기능을 못찾았습니다. (예를 들면 Dataset N개를 읽고 개별의 Dataset마다 파일로 만들어 하나의 zip으로 만들어 준다던지..)

물론 하둡의 경우 압축해주는 compress codec이 있지만 직접 Zip안의 파일명 등 섬세한 조작이 필요하여 JVM에서 파일들을 직접 byte로 읽어 일일이 하나의 Zip으로 만드는 방법으로 하니 잘되네요.


혹시 이 글을 보시고 하둡이나 스파크로 더 쉽게 구현할 수 있거나 라이브러리 기능이 있다면 알려주세요!