5

PDF、DOC、および DOCX ファイルを分析するプログラムを作成しています。これらのファイルは HDFS に保存されます。

MapReduce ジョブを開始するときに、マップ関数にファイル名をキーとして、バイナリ コンテンツを値として持たせたいと考えています。次に、PDF パーサー ライブラリに渡すことができるストリーム リーダーを作成します。マップ フェーズのキーと値のペアが filename/filecontents になるようにするにはどうすればよいですか?

Hadoop 0.20.2 を使用しています

これは、ジョブを開始する古いコードです。

public static void main(String[] args) throws Exception {
 JobConf conf = new JobConf(PdfReader.class);
 conf.setJobName("pdfreader");

 conf.setOutputKeyClass(Text.class);
 conf.setOutputValueClass(IntWritable.class);

 conf.setMapperClass(Map.class);
 conf.setReducerClass(Reduce.class);

 conf.setInputFormat(TextInputFormat.class);
 conf.setOutputFormat(TextOutputFormat.class);

 FileInputFormat.setInputPaths(conf, new Path(args[0]));
 FileOutputFormat.setOutputPath(conf, new Path(args[1]));

 JobClient.runJob(conf);
}

他のinputformatタイプがあることは知っています。しかし、私が望むことを正確に行うものはありますか? ドキュメントはかなり曖昧だと思います。利用可能なものがある場合、Map 関数の入力タイプはどのように見えるでしょうか?

前もって感謝します!

4

3 に答える 3

8

これに対する解決策は、これを行う独自のFileInputFormatクラスを作成することです。このFileInputFormatが受け取るFileSplit(getPath)から入力ファイルの名前にアクセスできます。FileInputformatのisSplitableを無効にして、常にfalseを返すようにしてください。

また、ファイル全体を単一の「レコード」値として返すカスタムRecordReaderも必要です。

大きすぎるファイルの取り扱いには注意してください。ファイル全体をRAMに効果的にロードし、タスクトラッカーのデフォルト設定では200MBのRAMのみを使用できます。

于 2011-04-20T19:59:13.917 に答える
1

WholeFileInputFormat を使用できます ( https://code.google.com/p/hadoop-course/source/browse/HadoopSamples/src/main/java/mr/wholeFile/?r=3 )

ファイルのマッパー名では、次のコマンドで取得できます。

public void map(NullWritable key, BytesWritable value, Context context) throws 
IOException, InterruptedException 
{       

Path filePath= ((FileSplit)context.getInputSplit()).getPath();
String fileNameString = filePath.getName();

byte[] fileContent = value.getBytes();

}
于 2013-12-10T13:35:53.777 に答える
1

別の方法として、バイナリ ファイルを hdfs に直接追加することもできます。次に、すべてのバイナリ ファイルの dfs パスを含む入力ファイルを作成します。これは、 Hadoop の FileSystemクラスを使用して動的に行うことができます。最後に、再び FileSystem を使用して、入力ストリームを開いて入力を処理するマッパーを作成します。

于 2011-04-19T12:57:28.560 に答える