2013-03-25 32 views
6

Tôi đang ghi đè phương thức "tiếp theo" của lớp RecordReader và "getRecordReader" của lớp TextInputFormat để gửi toàn bộ đoạn tới người lập bản đồ thay vì từng dòng một. (Tôi đang sử dụng api cũ và, định nghĩa cho đoạn tôi được nối thêm cho đến khi một dòng trống đi kèm trong tập tin văn bản của tôi.)
Dưới đây là mã của tôi:Ghi đè người đọc để đọc đoạn văn cùng một lúc thay vì dòng

public class NLinesInputFormat extends TextInputFormat 
{ 
    @Override 
    public RecordReader<LongWritable, Text> getRecordReader(InputSplit split, JobConf conf, Reporter reporter)throws IOException  { 
     reporter.setStatus(split.toString()); 
     return new ParagraphRecordReader(conf, (FileSplit)split); 
    } 
} 



public class ParagraphRecordReader implements RecordReader<LongWritable, Text> 
{ 
     private LineRecordReader lineRecord; 
     private LongWritable lineKey; 
     private Text lineValue; 
     public ParagraphRecordReader(JobConf conf, FileSplit split) throws IOException { 
      lineRecord = new LineRecordReader(conf, split); 
      lineKey = lineRecord.createKey(); 
      lineValue = lineRecord.createValue(); 
     } 

     @Override 
     public void close() throws IOException { 
      lineRecord.close(); 
     } 

     @Override 
     public LongWritable createKey() { 
      return new LongWritable(); 

     } 

     @Override 
     public Text createValue() { 
      return new Text(""); 

     } 

     @Override 
     public float getProgress() throws IOException { 
      return lineRecord.getPos(); 

     } 

     @Override 
     public synchronized boolean next(LongWritable key, Text value) throws IOException { 
      boolean appended, gotsomething; 
      boolean retval; 
      byte space[] = {' '}; 
      value.clear(); 
      gotsomething = false; 
      do { 
       appended = false; 
       retval = lineRecord.next(lineKey, lineValue); 
       if (retval) { 
        if (lineValue.toString().length() > 0) { 
         byte[] rawline = lineValue.getBytes(); 
         int rawlinelen = lineValue.getLength(); 
         value.append(rawline, 0, rawlinelen); 
         value.append(space, 0, 1); 
         appended = true; 
        } 
        gotsomething = true; 
       } 
      } while (appended); 

      //System.out.println("ParagraphRecordReader::next() returns "+gotsomething+" after setting value to: ["+value.toString()+"]"); 
      return gotsomething; 
     } 

     @Override 
     public long getPos() throws IOException { 
      return lineRecord.getPos(); 
     } 
    } 

Câu hỏi:
1. Tôi không tìm thấy bất kỳ hướng dẫn cụ thể về cách làm điều này, vì vậy có thể có một cái gì đó tôi đang làm sai xin vui lòng bình luận bất cứ đề nghị?
2. Tôi có thể biên dịch chính xác nhưng khi tôi thực hiện công việc của mình, người lập bản đồ của tôi liên tục chạy và tôi không thể tìm ra vấn đề ở đâu?

+0

Bạn đã thử chỉ với một đầu vào đoạn duy nhất? – Amar

+0

Tôi nghĩ bạn có lỗi; bạn sẽ nhận được thêm đoạn văn khi bạn chia tách. Tôi nghĩ rằng bạn cần phải phân biệt giữa việc chia tách bắt đầu từ 0 và mỗi phần tách khác. Dòng đầu tiên bắt đầu với 0 bắt đầu một đoạn văn, nhưng các phần tách sau bắt đầu bằng một dòng không nên bắt đầu một đoạn văn mới. (Thông thường, bạn đã đọc qua một ranh giới phân chia, vì vậy nếu phân chia của bạn có các dòng tiếp tục một đoạn, chúng sẽ được phát ra bởi phần chia trước đó). Tui bỏ lỡ điều gì vậy? –

Trả lời

3

Mã của bạn hoạt động hoàn toàn tốt cho tôi. Sự thay đổi duy nhất tôi đã làm là có các lớp này như lớp bên trong và làm cho chúng tĩnh.

tập tin đầu vào là như sau:

This is awesome. 
WTF is this. 

This is just a test. 

Mã mapper trông giống như:

@Override 
public void map(LongWritable key, Text value, OutputCollector<Text, Text> output, Reporter reporter) 
    throws IOException { 

    System.out.println(key+" : "+value); 
} 

đầu ra là:

0 : This is awesome. WTF is this. 
0 : This is just a test. 

tôi chắc chắn bạn sẽ ẩn náu không quên đặt định dạng đầu vào, nhưng chỉ trong trường hợp, hãy đặt nó là follo ws:

conf.setInputFormat(NLinesInputFormat.class); 
+0

Cảm ơn bạn đã trả lời Amar! .. và tôi đang sử dụng các lớp này là công khai tĩnh và cũng đặt Inputformat nhưng tôi không thử với đoạn văn nhỏ tôi đã thử nghiệm nó với một tệp lớn. Tôi sẽ làm điều đó và cho bạn biết làm thế nào nó đi. – JackSparrow

+0

Hey cảm ơn người đàn ông ... Tôi đã kiểm tra với tập tin đầu vào ngắn và nó làm việc tốt cho tập tin dài Đó là một số vấn đề định dạng tôi đã tìm ra nó! – JackSparrow

+0

@Amar im một người mới bắt đầu của hadoop, bạn có thể giải thích những gì đang xảy ra bên trong phương pháp tiếp theo? Bạn có thể giải thích cho tôi những logic thực hiện? Tôi cần ít giúp đỡ về điều này. – user1585111

Các vấn đề liên quan