2011-04-12 21 views
8

Bu temel bir soru olabilir, ancak Google’da bunun için bir yanıt bulamadım.
Çıkış dizininde birden çok çıktı dosyası oluşturan bir harita küçültme işim var. Java uygulamam bu işi uzak bir çalışan dizininde yürütür ve iş bittikten sonra çıktıyı org.apache.hadoop.fs.FileSystem API kullanarak programatik olarak okuması gerekir. Mümkün mü?
Uygulama, çıkış dizinini bilir, ancak harita azaltma işi tarafından oluşturulan çıktı dosyalarının adlarını bilmez. Bir dosya içeriklerini programlı olarak hadoop dosya sistemi API'sinde programlamanın bir yolu yok gibi görünüyor. Çıkış dosyaları nasıl okunacak?
Böyle bir durum senaryosu gibi görünüyor, bunun bir çözümü olduğuna eminim. Ama çok açık bir şey eksik.Hadoop Mapreduce Programının çıktısını program aracılığıyla okumak

cevap

19

Aradığınız yöntem, listStatus (Yol) olarak adlandırılır. Sadece bir Dosyanın içindeki tüm dosyaları FileStatus dizisi olarak döndürür. Daha sonra basitçe bir döngü nesnesi oluşturabilir ve okuyabilirsiniz. Eğer okuyucu böyle kurulum yapabilirsiniz Hadoop 2.x için

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

:

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

sayesinde Yardımlarınız için çok. – nabeelmukhtar

+1

@Thomas, listStatus ayrıca başka dosyaları döndürmek gibi görünüyor, örn. _SUCCESS –

+0

Evet, ama bu benim sorunum değil;) Kendiniz için filtre etmeniz gerekiyor –

0

Birkaç seçenek vardır: Burada bazen kullanmak iki.

Yöntem 1.

: Veri büyüklüğüne bağlı olarak (Madde 6 here bulundu)

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 

"Bu HDF'ler dosyaları HDF'ler-çıkışı-birleştirir aşağıdaki HDF'ler faydalanmak için komutları dir/part- * tek bir yerel dosyaya. "

Sonra tek bir dosyada okuyabilirsiniz. (Bu HDF'ler yerel deposunda olup unutmayın)

Yöntem 2.: (Bir Yapılandırma, FileSystem örneklerini içeren HDF'ler denilen sınıf hem de diğer yardımcı yöntemler var)

: Bir yardımcı yöntemini oluştur
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; 
    } 

Daha sonra böyle bir komut aracılığıyla çağırabilirsiniz: hdfs.matchFiles("/user/kenny/mrjob/", "part-")

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); 
      } 
İlgili konular