8
votes

Lecture programmée de la production du programme Hadoop Mapreduce

Cela peut être une question fondamentale, mais je ne pouvais pas trouver une réponse pour cela sur Google.
J'ai un travail de carte de carte de carte qui crée plusieurs fichiers de sortie dans son répertoire de sortie. Mon application Java exécute ce travail sur un cluster de hadoop distant et, une fois le travail terminé, il doit lire la sortie par programme à l'aide de org.apache.hadoop.fs.filesystem API. Est-ce possible?
L'application connaît le répertoire de sortie, mais pas les noms des fichiers de sortie générés par le travail de la carte. Il semble qu'il n'ya aucun moyen de répertorier de manière programmative le contenu d'un répertoire dans l'API du système de fichiers Hadoop. Comment les fichiers de sortie seront-ils lus?
Cela semble un scénario aussi banal que je suis sûr qu'il a une solution. Mais il me manque quelque chose de très évident.


0 commentaires

3 Réponses :


20
votes

La méthode que vous recherchez s'appelle ListStatus (chemin). Il renvoie simplement tous les fichiers à l'intérieur d'un chemin comme une matrice de filestatus. Ensuite, vous pouvez simplement boucler sur eux créer un objet chemin de chemin et la lire.

 SequenceFile.Reader reader = 
           new SequenceFile.Reader(conf, SequenceFile.Reader.file(path))


6 commentaires

@Thomas, liststatus semble également retourner d'autres fichiers, par exemple. _SUCCÈS


Oui, mais ce n'est pas mon problème;) Vous devez filtrer pour vous-même


Pouvez-vous s'il vous plaît me guider comment filtrer les fichiers _success?


@waqas utilise Pathfilter ( Hadoop .apache.org / Common / Docs / R0.20.2 / API / ORG / APACHE / Hadoop / FS / ... ) et l'API du système de fichiers ci-dessus.


"Nouvelle séquencefile.reader (FS, chemin, Conf);" est obsolète en 2.0.0-CDH4.0.1


@XGMZ YEP Il a été remplacé par configuration , lecteur.option . Fonctionne fondamentalement de la même manière. Vous avez juste besoin de le graver avec le fichierOption qui prend le chemin comme argument.



0
votes

Vous avez quelques options: voici deux que j'utilise parfois.

Méthode n ° 1: Strong> Selon votre taille de données, consiste à utiliser les commandes HDFS suivantes (trouvées ici , article 6) p>

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;
    }


0 commentaires

0
votes
            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);
            }

0 commentaires