2013-09-25 10 views

Odpowiedz

11

Użyj tego wewnątrz odwzorowującym:

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

Edit:

Spróbuj tego, jeśli chcesz to zrobić wewnątrz configure() przez starego API:

+0

Próbuję użyć '' context'', ale nie ma metody o nazwie '' getInputSplit''. Czy używam starego API? Poza tym, czy mogę to zrobić w funkcji konfiguracji zamiast programu odwzorowującego? –

+0

Zobacz powyższą edycję. – Tariq

+0

Z najnowszym hadoop 2.6.0 to nie działa w mapreduce, możesz to zasugerować. – Raghuveer

41

Najpierw musisz uzyskać podział wejściowy, używając e nowsze mapreduce API byłoby to zrobić w następujący sposób:

context.getInputSplit(); 

Jednak aby uzyskać ścieżkę i nazwę pliku, trzeba będzie najpierw typecast wynik do FileSplit.

Tak, aby uzyskać ścieżkę pliku wejściowego można wykonać następujące czynności:

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

Podobnie, aby uzyskać nazwę pliku, może po prostu wezwać getName() w następujący sposób:

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

upewnij się, że wybrałeś odpowiednią klasę do włączenia (mapred vs mapreduce) – Gavriel

+0

Z ciekawości, jak to określiłeś na zewnątrz? Dokumentacja getInputSplit nie sugeruje, że jest to możliwe (przynajmniej dla mnie ...). – Mzzzzzz

1

Musisz najpierw przekonwertować do InputSplit przez typowanie, a następnie musisz wpisać rzut do FileSplit.

Przykład:

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

Jeśli używasz Hadoop Streaming, można użyć JobConf variables in a streaming job's mapper/reducer.

Co do nazwy pliku wejściowego odwzorowującym, zobacz sekcję Configured Parameters, zmienną map.input.file (nazwę pliku, który mapa czyta z) jest tym, który może wykonać zadania. Należy jednak pamiętać, że:

Uwaga: Podczas wykonywania zadania przesyłania strumieniowego nazwy parametrów "odwzorowanych" są przekształcane. Kropki (.) Stają się podkreśleniami (_). Na przykład mapred.job.id staje się mapred_job_id, a mapred.jar staje się mapred_jar. Aby uzyskać wartości w programie odwzorowującym/redukującym zadania strumieniowania, należy użyć nazw parametrów z podkreślnikami.


Na przykład, jeśli używasz Python, a następnie można umieścić tę linię w pliku odwzorowujący:

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

To działało lokalnie, ale w EMR przy użyciu przędzy, musiałem użyć sugestii w http://stackoverflow.com/questions/20915569/how-can-to-get-the-filename-from-a-streaming-mapreduce- job-in-r W szczególności: 'os.getenv ('mapreduce_map_input_file')' –

3

zauważony na Hadoop 2.4 i większa pomocą stare api metoda ta tworzy wartość null

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

Alternatywnie można wykorzystać obiekt Reporter przekazany do funkcji mapie, aby uzyskać InputSplit i obsady do FileSplit aby pobrać nazwę pliku

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

dla org.apache.hadood.mapred pakietu mapa podpis funkcja powinna być:

map(Object, Object, OutputCollector, Reporter) 

Tak więc, aby dostać t on nazwę pliku wewnątrz funkcji mapy, można użyć obiektu Reporter takiego:

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

Jeśli używasz zwykłego InputFormat, to wykorzystać w swojej Mapper:

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

Jeśli jesteś przy użyciu CombineFileInputFormat, jest to inne podejście, ponieważ łączy kilka małych plików w jeden stosunkowo duży plik (w zależności od konfiguracji). Zarówno Mapper, jak i RecordReader działają na tej samej maszynie JVM, dzięki czemu można przesyłać między nimi dane podczas pracy. Trzeba zaimplementować własną CombineFileRecordReaderWrapper i wykonaj następujące czynności:

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

Następnie w Mapper, użyj tego:

String currentFileName = MyCombineFileRecordReaderWrapper.getCurrentFilePath() 

nadzieję, że pomogło :-)

1

To pomogło mi:

String fileName = ((org.apache.hadoop.mapreduce.lib.input.FileSplit) context.getInputSplit()).getPath().getName(); 
Powiązane problemy