2013-09-25 34 views

Trả lời

11

Sử dụng này bên trong mapper của bạn:

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

Edit:

Hãy thử điều này nếu bạn muốn làm điều đó bên configure() qua API cũ:

+0

Tôi cố gắng sử dụng '' context'' nhưng không có phương thức được gọi là '' getInputSplit''. Tôi có đang sử dụng API cũ không? Bên cạnh đó, tôi có thể làm những việc này trong chức năng cấu hình thay vì trình ánh xạ không? –

+0

Xem chỉnh sửa ở trên. – Tariq

+0

Với phiên bản mới nhất 2.6.0 hadoop này không hoạt động trong mapreduce bạn có thể đề xuất về điều này. – Raghuveer

41

Trước tiên, bạn cần lấy phần tách đầu vào, sử dụng thứ e API Mapreduce mới hơn, nó sẽ được thực hiện như sau:

context.getInputSplit(); 

Nhưng để có được đường dẫn tệp và tên tệp bạn cần trước tiên hãy nhập kết quả vào FileSplit.

Vì vậy, để có được các đường dẫn tập tin đầu vào bạn có thể làm như sau:

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

Tương tự như vậy, để có được tên tập tin, bạn có thể chỉ kêu gọi getName(), như thế này:

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

đảm bảo bạn đã chọn đúng lớp học để đưa vào (mapred vs mapreduce) – Gavriel

+0

Vì tò mò, bạn đã hình dung ra điều này như thế nào ngoài? Tài liệu của getInputSplit không gợi ý rằng điều này là có thể (ít nhất là với tôi ...). – Mzzzzzz

1

Trước tiên, bạn phải chuyển đổi sang InputSplit bằng typecasting và sau đó bạn cần nhập truyền vào FileSplit.

Ví dụ:

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

Nếu bạn đang sử dụng Hadoop Streaming, bạn có thể sử dụng JobConf variables in a streaming job's mapper/reducer.

Đối với các tên tập tin đầu vào của mapper, xem Configured Parameters phần, biến map.input.file (tên tập tin đó bản đồ đang đọc từ) là người có thể hoàn thành công việc. Nhưng lưu ý rằng:

Lưu ý: Trong khi thực thi lệnh truyền trực tuyến, tên của thông số "bản đồ" được chuyển đổi. Các dấu chấm (.) Trở thành dấu gạch dưới (_). Ví dụ, mapred.job.id trở thành mapred_job_id và mapred.jar trở thành mapred_jar. Để có được các giá trị trong trình ánh xạ/bộ giảm tốc của công việc phát trực tuyến, hãy sử dụng tên tham số có dấu gạch dưới.


Ví dụ, nếu bạn đang sử dụng Python, sau đó bạn có thể đặt dòng này trong tập tin ánh xạ của bạn:

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

Điều này làm việc cục bộ, nhưng trong EMR sử dụng Sợi, tôi cần sử dụng đề xuất trong http://stackoverflow.com/questions/20915569/how-can-to-get-the-filename-from-a-streaming-mapreduce- job-in-r Cụ thể: 'os.getenv ('mapreduce_map_input_file')' –

3

Nhận thấy trên Hadoop 2.4 và lớn hơn bằng cách sử dụng api phương pháp này tạo ra một giá trị null

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

Hoặc bạn có thể sử dụng các đối tượng Reporter truyền cho chức năng bản đồ của bạn để có được những InputSplit và dàn diễn viên với một FileSplit để lấy tên tập tin

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

Đối org.apache.hadood.mapred gói bản đồ chức năng chữ ký nên là:

map(Object, Object, OutputCollector, Reporter) 

Vì vậy, để có được t ông tên file bên trong hàm bản đồ, bạn có thể sử dụng đối tượng Reporter như thế này:

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

Nếu bạn đang sử dụng InputFormat thường xuyên, sử dụng này trong Mapper của bạn:

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

Nếu bạn bằng cách sử dụng CombineFileInputFormat, đó là một cách tiếp cận khác vì nó kết hợp một số tệp nhỏ vào một tệp tương đối lớn (phụ thuộc vào cấu hình của bạn). Cả Mapper và RecordReader đều chạy trên cùng một JVM để bạn có thể truyền dữ liệu giữa chúng khi chạy. Bạn cần phải thực hiện CombineFileRecordReaderWrapper của riêng bạn và làm như sau:

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

Sau đó, trong Mapper của bạn, sử dụng này:

String currentFileName = MyCombineFileRecordReaderWrapper.getCurrentFilePath() 

Hope tôi đã giúp :-)

1

này đã giúp tôi:

String fileName = ((org.apache.hadoop.mapreduce.lib.input.FileSplit) context.getInputSplit()).getPath().getName(); 
Các vấn đề liên quan