Как я могу получить имя входного файла внутри mapper? У меня есть несколько входных файлов, хранящихся во входной директории, каждый из которых может считывать другой файл, и мне нужно знать, какой файл читатель просматривал.
Как получить имя входного файла в Mapper в программе Hadoop?
Ответ 1
Сначала вам нужно получить разделение ввода, используя новый API 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
Используйте это внутри своего картографа:
FileSplit fileSplit = (FileSplit)context.getInputSplit();
String filename = fileSplit.getPath().getName();
Изменить:
Попробуйте, если вы хотите сделать это внутри configure() через старый API:
String fileName = new String();
public void configure(JobConf job)
{
filename = job.get("map.input.file");
}
Ответ 3
Если вы используете Hadoop Streaming, вы можете использовать переменные JobConf в трансляторе/редукторе потока.
Что касается имени входного файла mapper, см. раздел Конфигурируемые параметры, то переменная map.input.file
(имя файла, с которой карта считывается) является той, может получить работу. Но обратите внимание:
Примечание. Во время выполнения потокового задания имена "отображенных" параметров преобразуются. Точки (.) Становятся символами подчеркивания (_). Например, mapred.job.id становится mapred_job_id, а mapred.jar становится mapred_jar. Для получения значений в потоковом задатчике/редукторе используйте имена параметров с символами подчеркивания.
Например, если вы используете Python, вы можете поместить эту строку в файл mapper:
import os
file_name = os.getenv('map_input_file')
print file_name
Ответ 4
Заметьте, что Hadoop 2.4 и выше с использованием старого api этот метод создает нулевое значение
String fileName = new String();
public void configure(JobConf job)
{
fileName = job.get("map.input.file");
}
В качестве альтернативы вы можете использовать объект Reporter, переданный вашей функции карты, чтобы получить InputSplit и передать в FileSplit для получения имени файла
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();
....
}
Ответ 5
Вы должны сначала преобразовать в InputSplit с помощью typecasting, а затем вам нужно ввести cast в FileSplit.
Пример:
InputSplit inputSplit= (InputSplit)context.getInputSplit();
Path filePath = ((FileSplit) inputSplit).getPath();
String filePathString = ((FileSplit) context.getInputSplit()).getPath().toString()
Ответ 6
Если вы используете обычный InputFormat, используйте его в своем 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()
Если вы используете CombineFileInputFormat, это другой подход, потому что он объединяет несколько небольших файлов в один относительно большой файл (зависит от вашей конфигурации). Оба Mapper и RecordReader работают на одной JVM, поэтому вы можете передавать данные между ними при запуске. Вам необходимо реализовать свой собственный CombineFileRecordReaderWrapper и сделать следующее:
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;
}
...
Затем в вашем Mapper используйте это:
String currentFileName = MyCombineFileRecordReaderWrapper.getCurrentFilePath()
Надеюсь, я помог: -)
Ответ 7
Это помогло мне:
String fileName = ((org.apache.hadoop.mapreduce.lib.input.FileSplit) context.getInputSplit()).getPath().getName();
Ответ 8
Для пакета org.apache.hadood.mapred
подпись функции карты должна быть:
map(Object, Object, OutputCollector, Reporter)
Итак, чтобы получить имя файла внутри функции карты, вы можете использовать объект Reporter следующим образом:
String fileName = ((FileSplit) reporter.getInputSplit()).getPath().getName();