8

これは基本的な質問かもしれませんが、Googleで答えを見つけることができませんでした。
出力ディレクトリに複数の出力ファイルを作成するmap-reduceジョブがあります。私のJavaアプリケーションは、リモートのHadoopクラスターでこのジョブを実行します。ジョブが終了したら、org.apache.hadoop.fs.FileSystemAPIを使用してプログラムで出力を読み取る必要があります。出来ますか?
アプリケーションは出力ディレクトリを認識していますが、map-reduceジョブによって生成された出力ファイルの名前は認識していません。HadoopファイルシステムAPIでディレクトリの内容をプログラムで一覧表示する方法はないようです。出力ファイルはどのように読み取られますか?
それはとてもありふれたシナリオのように思われるので、私はそれが解決策を持っていると確信しています。しかし、私は非常に明白な何かを見逃しています。

4

3 に答える 3

20

探しているメソッドはlistStatus(Path)と呼ばれます。パス内のすべてのファイルをFileStatus配列として返すだけです。次に、それらをループしてパスオブジェクトを作成し、それを読み取ることができます。

    FileStatus[] fss = fs.listStatus(new Path("/"));
    for (FileStatus status : fss) {
        Path path = status.getPath();
        SequenceFile.Reader reader = new SequenceFile.Reader(fs, path, conf);
        IntWritable key = new IntWritable();
        IntWritable value = new IntWritable();
        while (reader.next(key, value)) {
            System.out.println(key.get() + " | " + value.get());
        }
        reader.close();
    }

Hadoop 2.xの場合、リーダーを次のように設定できます。

 SequenceFile.Reader reader = 
           new SequenceFile.Reader(conf, SequenceFile.Reader.file(path))
于 2011-04-12T12:28:49.483 に答える
0

いくつかのオプションがあります。これが私が時々使用する2つです。

方法1:データサイズに応じて、次のHDFSコマンドを使用します(ここにあります、項目6)

hadoop fs -getmerge hdfs-output-dir local-file
// example 
hadoop fs -getmerge /user/kenny/mrjob/ /tmp/mrjob_output
// another way
hadoop fs -cat /user/kenny/mrjob/part-r-* > /tmp/mrjob_output

「これにより、HDFSファイルhdfs-output-dir /part-*が単一のローカルファイルに連結されます。」

そうすれば、1つのファイルを読み取ることができます。(HDFSではなくローカルストレージにあることに注意してください)

方法2:ヘルパーメソッドを作成します:(構成、ファイルシステムインスタンス、およびその他のヘルパーメソッドを含むHDFSというクラスがあります)

public List<Path> matchFiles(String path, final String filter) {
        List<Path> matches = new LinkedList<Path>();
        try {
            FileStatus[] statuses = fileSystem.listStatus(new Path(path), new PathFilter() {
                       public boolean accept(Path path) {
                          return path.toString().contains(filter);
                       }
                    });  
            for(FileStatus status : statuses) {
                matches.add(status.getPath());
            }
        } catch(IOException e) {
        LOGGER.error(e.getMessage(), e);
        }
        return matches;
    }

次に、次のようなコマンドを使用して呼び出すことができます。hdfs.matchFiles("/user/kenny/mrjob/", "part-")

于 2013-06-17T12:43:15.590 に答える
0
            FSDataInputStream inputStream = fs.open(path);
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            String record;
            while((record = reader.readLine()) != null) {
                int blankPos = record.indexOf(" ");
                System.out.println(record+"blankPos"+blankPos);
                String keyString = record.substring(0, blankPos);
                String valueString = record.substring(blankPos + 1);
                System.out.println(keyString + " | " + valueString);
            }
于 2016-01-14T12:17:14.587 に答える