2013-09-25 3 views
32

मैपर के भीतर इनपुट फ़ाइल का नाम कैसे प्राप्त कर सकता हूं? मेरे पास इनपुट निर्देशिका में संग्रहीत कई इनपुट फ़ाइलें हैं, प्रत्येक मैपर एक अलग फ़ाइल पढ़ सकता है, और मुझे पता होना चाहिए कि मैपर ने कौन सी फाइल पढ़ी है।एक हडोप प्रोग्राम में मैपर में इनपुट फ़ाइल नाम कैसे प्राप्त करें?

उत्तर

11

उपयोग यह आपके नक्शाकार अंदर:

FileSplit fileSplit = (FileSplit)context.getInputSplit(); 
String filename = fileSplit.getPath().getName(); 

संपादित करें:

:

वर्ष एपीआई के माध्यम से अगर आप कॉन्फ़िगर (अंदर यह करना चाहते हैं यह प्रयास करें)

+0

मैं उपयोगकर्ता 'संदर्भ' के लिए प्रयास करता हूं लेकिन 'getInputSplit'' नामक विधि नहीं है। क्या मैं पुरानी एपीआई का उपयोग कर रहा हूं? इसके अलावा, क्या मैं इन चीजों को मैपर के बजाय कॉन्फ़िगरेशन फ़ंक्शन में कर सकता हूं? –

+0

उपरोक्त संपादन देखें। – Tariq

+0

नवीनतम हैडऑप 2.6.0 के साथ यह मैड्रिड में काम नहीं करता है क्या आप इस पर सुझाव दे सकते हैं। – Raghuveer

41

सबसे पहले आपको इनपुट विभाजन को प्राप्त करने की आवश्यकता है, वें का उपयोग कर ई नए mapreduce एपीआई इस प्रकार यह किया जा सकता:

context.getInputSplit(); 

लेकिन आदेश फ़ाइल पथ और फ़ाइल नाम आप पहली बार FileSplit में परिणाम टाइपकास्ट करने की आवश्यकता होगी प्राप्त करने के लिए।

तो, आदेश इनपुट फ़ाइल पथ प्राप्त करने के लिए आप कर सकते हैं निम्नलिखित:

Path filePath = ((FileSplit) context.getInputSplit()).getPath(); 
String filePathString = ((FileSplit) context.getInputSplit()).getPath().toString(); 

इसी प्रकार, फ़ाइल नाम पाने के लिए, आप बस getName() पर, कॉल कर सकते हैं इस तरह:

String fileName = ((FileSplit) context.getInputSplit()).getPath().getName(); 
+2

सुनिश्चित करें कि आपने शामिल करने के लिए सही वर्ग चुना है (नक्शा बनाम मैपरेडस) – Gavriel

+0

जिज्ञासा से, आप इसे कैसे समझते हैं बाहर? GetInputSplit का प्रलेखन यह सुझाव नहीं देता है कि यह संभव है (कम से कम मेरे लिए ...)। – Mzzzzzz

1

आपको पहले टाइपस्केटिंग द्वारा इनपुटस्प्लिट में कनवर्ट करना होगा और फिर आपको फ़ाइलस्प्लिट में कास्ट टाइप करना होगा।

उदाहरण:

InputSplit inputSplit= (InputSplit)context.getInputSplit(); 
Path filePath = ((FileSplit) inputSplit).getPath(); 
String filePathString = ((FileSplit) context.getInputSplit()).getPath().toString() 
10

आप Hadoop Streaming का उपयोग कर रहे हैं, तो आप JobConf variables in a streaming job's mapper/reducer.

नक्शाकार के इनपुट फ़ाइल नाम के रूप में उपयोग कर सकते हैं, Configured Parameters अनुभाग, map.input.file चर (फ़ाइल नाम देखते हैं कि नक्शा से पढ़ रहा है) क्या कोई काम पूरा कर सकता है। लेकिन ध्यान दें कि:

नोट: स्ट्रीमिंग नौकरी के निष्पादन के दौरान, "मानचित्रित" पैरामीटर के नाम बदल दिए जाते हैं। डॉट्स (।) अंडरस्कोर (_) बन जाते हैं। उदाहरण के लिए, mapred.job.id mapred_job_id बन जाता है और mapred.jar mapred_jar बन जाता है। स्ट्रीमिंग जॉब के मैपर/रेड्यूसर में मान प्राप्त करने के लिए अंडरस्कोर के साथ पैरामीटर नामों का उपयोग करें।


उदाहरण के लिए, यदि आप अजगर का उपयोग कर रहे हैं, तो आप इस लाइन अपने नक्शाकार फ़ाइल में डाल कर सकते हैं:

import os 
file_name = os.getenv('map_input_file') 
print file_name 
+3

यह स्थानीय रूप से काम करता था, लेकिन यार्न का उपयोग करके ईएमआर में, मुझे http://stackoverflow.com/questions/20915569/how-can-to-get-the-filename-from-a-streaming-mapreduce- में सुझाव का उपयोग करने की आवश्यकता थी। जॉब-इन-आर विशेष रूप से: 'os.getenv (' mapreduce_map_input_file ') ' –

3

Hadoop 2 पर देखा।4 और अधिक से अधिक वर्ष एपीआई इस विधि एक शून्य मान पैदा करता है का उपयोग कर

String fileName = new String(); 
public void configure(JobConf job) 
{ 
    fileName = job.get("map.input.file"); 
} 

वैकल्पिक रूप से आप फ़ाइल नाम

पुनः प्राप्त करने के रिपोर्टर वस्तु एक FileSplit में अपना नक्शा समारोह InputSplit पाने के लिए और कलाकारों के लिए पारित उपयोग कर सकते हैं
public void map(LongWritable offset, Text record, 
     OutputCollector<NullWritable, Text> out, Reporter rptr) 
     throws IOException { 

    FileSplit fsplit = (FileSplit) rptr.getInputSplit(); 
    String inputFileName = fsplit.getPath().getName(); 
    .... 
} 
0

org.apache.hadood.mapred पैकेज के लिए नक्शा समारोह हस्ताक्षर किया जाना चाहिए:

map(Object, Object, OutputCollector, Reporter) 

तो, प्राप्त करने के लिए टी वह नक्शा समारोह के अंदर फ़ाइल नाम, तो आप इस तरह रिपोर्टर वस्तु इस्तेमाल कर सकते हैं: यदि आप नियमित रूप से InputFormat उपयोग कर रहे हैं

String fileName = ((FileSplit) reporter.getInputSplit()).getPath().getName(); 
1

, अपने मैपर में इस का उपयोग करें:

InputSplit is = context.getInputSplit(); 
Method method = is.getClass().getMethod("getInputSplit"); 
method.setAccessible(true); 
FileSplit fileSplit = (FileSplit) method.invoke(is); 
String currentFileName = fileSplit.getPath().getName() 

यदि आप CombineFileInputFormat का उपयोग करके, यह एक अलग दृष्टिकोण है क्योंकि यह कई छोटी फ़ाइलों को एक अपेक्षाकृत बड़ी फ़ाइल में जोड़ता है (आपकी कॉन्फ़िगरेशन पर निर्भर करता है)। मैपर और रिकॉर्डर दोनों एक ही जेवीएम पर चलते हैं ताकि आप चलते समय उनके बीच डेटा पास कर सकें। आप इस प्रकार अपने स्वयं के CombineFileRecordReaderWrapper को लागू करने और क्या करने की जरूरत:

String currentFileName = MyCombineFileRecordReaderWrapper.getCurrentFilePath() 

आशा मैं :-)

1

यह मैं मदद की मदद की:

public class MyCombineFileRecordReaderWrapper<K, V> extends RecordReader<K, V>{ 
... 
private static String mCurrentFilePath; 
... 
public void initialize(InputSplit combineSplit , TaskAttemptContext context) throws IOException, InterruptedException { 
     assert this.fileSplitIsValid(context); 
     mCurrentFilePath = mFileSplit.getPath().toString(); 
     this.mDelegate.initialize(this.mFileSplit, context); 
    } 
... 
public static String getCurrentFilePath() { 
     return mCurrentFilePath; 
    } 
... 

फिर, अपने मैपर में, इस का उपयोग करें:

String fileName = ((org.apache.hadoop.mapreduce.lib.input.FileSplit) context.getInputSplit()).getPath().getName(); 
संबंधित मुद्दे