MultipleOutputs.addNamedOutput(job, "OutputFileName", OutputFormatClass, keyClass, valueClass);
API는 두이를 위해 기록 방법을 과부하 제공한다. 출력 디렉토리를 별도의 출력 파일을 작성하는 지금
multipleOutputs.write("OutputFileName", new Text(Key), new Text(Value));
는, 당신은 기본 출력 경로에 대한 추가 매개 변수를 사용하여 오버로드 쓰기 방법을 사용해야합니다. multipleOutputs.write("OutputFileName", new Text(key), new Text(value), baseOutputPath);
하면 출력 파일의 3 개 가지 세트를 작성한다고 가정, 첫 번째 단계는 드라이버에 지정된 출력 파일을 등록하는 것입니다 또한
MultipleOutputs.addNamedOutput(job, "set1", OutputFormatClass, keyClass, valueClass);
MultipleOutputs.addNamedOutput(job, "set2", OutputFormatClass, keyClass, valueClass);
MultipleOutputs.addNamedOutput(job, "set3", OutputFormatClass, keyClass, valueClass);
, 서로 다른 출력 디렉토리 또는 원하는 디렉토리 구조를 만들 드라이버 코드에서 실제 출력 디렉토리와 함께 :
Path set1Path = new Path("/hdfsRoot/outputs/set1");
Path set2Path = new Path("/hdfsRoot/outputs/set2");
Path set3Path = new Path("/hdfsRoot/outputs/set3");
마지막으로 중요한 단계는 이름을 기반으로 출력 파일의 이름을 바꾸는 것입니다. 작업이 성공적이면;
FileSystem fileSystem = FileSystem.get(new Configuration);
if (jobStatus == 0) {
// Get the output files from the actual output path
FileStatus outputfs[] = fileSystem.listStatus(outputPath);
// Iterate over all the files in the output path
for (int fileCounter = 0; fileCounter < outputfs.length; fileCounter++) {
// Based on each fileName rename the path.
if (outputfs[fileCounter].getPath().getName().contains("set1")) {
fileSystem.rename(outputfs[fileCounter].getPath(), new Path(set1Path+"/"+anyNewFileName));
} else if (outputfs[fileCounter].getPath().getName().contains("set2")) {
fileSystem.rename(outputfs[fileCounter].getPath(), new Path(set2Path+"/"+anyNewFileName));
} else if (outputfs[fileCounter].getPath().getName().contains("set3")) {
fileSystem.rename(outputfs[fileCounter].getPath(), new Path(set3Path+"/"+anyNewFileName));
}
}
}
참고 : 우리는 한 디렉토리에서 다른 디렉토리로 파일을 이동하기 때문에이 작업에 상당한 오버 헤드를 추가하지 않습니다. 특정 접근 방식을 선택하는 것은 구현의 성격에 달려 있습니다.
요약하면이 방법은 기본적으로 동일한 출력 디렉토리에 다른 이름을 사용하는 모든 출력 파일을 작성하고 작업이 성공적으로 완료되면 기본 출력 경로의 이름을 바꾸고 다른 출력 디렉토리로 파일을 이동합니다.
질문 2 : 입력 폴더 (들)에서 특정 파일 읽기 :
당신은 확실히 MultipleInputs 클래스를 사용하여 디렉토리에서 특정 입력 파일을 읽을 수 있습니다.
입력 경로/파일 이름에 따라 입력 파일을 해당 매퍼 구현에 전달할 수 있습니다.
사례 1 :
FileStatus inputfs[] = fileSystem.listStatus(inputPath);
for (int fileCounter = 0; fileCounter < inputfs.length; fileCounter++) {
if (inputfs[fileCounter].getPath().getName().contains("set1")) {
MultipleInputs.addInputPath(job, inputfs[fileCounter].getPath(), TextInputFormat.class, Set1Mapper.class);
} else if (inputfs[fileCounter].getPath().getName().contains("set2")) {
MultipleInputs.addInputPath(job, inputfs[fileCounter].getPath(), TextInputFormat.class, Set2Mapper.class);
} else if (inputfs[fileCounter].getPath().getName().contains("set3")) {
MultipleInputs.addInputPath(job, inputfs[fileCounter].getPath(), TextInputFormat.class, Set3Mapper.class);
}
}
사례 2 : 모든 입력 파일은 하나의 디렉토리에있는 경우
우리가 할 수있는 모든 입력 파일은 하나의 디렉토리에없는 경우 기본적으로 입력 파일이 다른 디렉토리에 있더라도 위의 동일한 접근 방식을 사용합니다. 기본 입력 경로를 반복하고 파일 경로 이름에서 일치 기준을 확인하십시오.
파일이 완전히 다른 위치에 있으면 가장 간단한 방법은 여러 입력에 개별적으로 추가하는 것입니다.
MultipleInputs.addInputPath(job, Set1_Path, TextInputFormat.class, Set1Mapper.class);
MultipleInputs.addInputPath(job, Set2_Path, TextInputFormat.class, Set2Mapper.class);
MultipleInputs.addInputPath(job, Set3_Path, TextInputFormat.class, Set3Mapper.class);
희망이 있습니다. 고맙습니다.
대답을 좀 자세히 설명해 주시겠습니까? MultipleOutputs 코드를 어떻게 복사합니까? –
답장을 보내 주셔서 감사합니다 –
그것은 일했습니다! 다른 폴더로 출력 할 수 있습니다 ... –