Подтвердить что ты не робот

Как получить имя входного файла в Mapper в программе Hadoop?

Как я могу получить имя входного файла внутри mapper? У меня есть несколько входных файлов, хранящихся во входной директории, каждый из которых может считывать другой файл, и мне нужно знать, какой файл читатель просматривал.

4b9b3361

Ответ 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();