2014-11-29 40 views
5

Tôi đã tải xuống ảnh chụp mime4j 0.8.0 từ subversion và tạo nó với maven. Các lọ liên quan tôi tạo ra có thể được tìm thấy here.Mime4j: DefaultMessageBuilder không phân tích cú pháp nội dung mbox

Bây giờ tôi cố gắng phân tích cú pháp a toy mbox file từ thử nghiệm mime4j.

Tôi sử dụng số sample code này. Tóm lại:

final File mbox = new File("c:\\mbox.rlug"); 
int count = 0; 
for (CharBufferWrapper message : MboxIterator.fromFile(mbox).charset(ENCODER.charset()).build()) { 
    System.out.println(messageSummary(message.asInputStream(ENCODER.charset()))); 
    count++; 
} 
System.out.println("Found " + count + " messages"); 

+

private static String messageSummary(InputStream messageBytes) throws IOException, MimeException { 
    MessageBuilder builder = new DefaultMessageBuilder(); 
    Message message = builder.parseMessage(messageBytes); 
    return String.format("\nMessage %s \n" + 
      "Sent by:\t%s\n" + 
      "To:\t%s\n", 
      message.getSubject(), 
      message.getSender(), 
      message.getTo()); 
} 

Đầu ra là:

nhắn rỗng Sent by: null Để: null

nhắn rỗng Sent by: null Để: null

Tin nhắn null Đã gửi bởi: null Tới: null

nhắn rỗng Sent by: null Để: null

nhắn rỗng Sent by: null Để: null

Tìm thấy 5 tin nhắn

Có thực sự 5 tin nhắn, nhưng tại sao tất cả các lĩnh vực vô giá trị?

+0

Bạn có thể in thông báo thô trong vòng lặp để xem liệu nó có được xây dựng chính xác không? 'System.out.println (message);' – ToYonos

Trả lời

2

tôi thấy vấn đề.

DefaultMessageBuilder không phân tích cú pháp các tệp mbox có dấu tách dòng cửa sổ \r\n. Khi thay thế chúng bằng dấu phân tách dòng UNIX \n hoạt động phân tích cú pháp.

Đây là vấn đề quan trọng vì tệp mbox được tải xuống từ Gmail sử dụng \r\n.

+0

Bạn có thể muốn gửi yêu cầu thay đổi cho dự án jache apache. Kinh nghiệm của tôi với cộng đồng là tốt. –

1

Tôi đã tải xuống tệp jar, mã mẫu mà bạn đã trỏ đến và tệp mbox mẫu mà bạn đã trỏ tới, biên dịch mẫu (không có thay đổi) và chạy tệp đó đối với tệp mbox mẫu.

Nó hoạt động như mong đợi (các trường chứa dữ liệu dự kiến, không phải null). Đây là trên máy Mac với Java 1.6_0_65, và cũng với 1.8.0_11

Output là như sau:

$ java -cp:. Apache-mime4j-core-0.8.0-SNAPSHOT. jar: apache-mime4j-dom-0.8.0-SNAPSHOT.jar: apache-mime4j-mbox-iterator-0.8.0-SNAPSHOT.jar IterateOverMbox mbox.rlug.txt

Thông báo Din windows ma pot, din LINUX NU ma pot conecta (la ZAPP) Gửi bởi: [email protected] Tới: [[email protected]]

Thông báo Re: Đĩa mềm khởi động RH 8.0 Gửi bởi: [email protected] Để: [[email protected]]

nhắn Qmail mysql virtualusers + ssl + smtp auth + pop3 gửi bởi: [email protected] Để: [rlug @ lug.ro]

nhắn Re: Din nồi cửa sổ ma, din LINUX NU ma nồi conecta (la Zapp) Sent by: [email protected] Để: [[email protected]]

Tin nhắn LSTP vấn đề - giải quyết Được gửi bởi: [email protected] Tới: [rlug @ lug.ro]

Tìm thấy 5 tin nhắn Làm tại: 108 milis

+0

Nó không thành công với tôi trên hai máy tính Windows. Tôi sẽ thử hệ điều hành khác – zvisofer

+0

cũng đã thử với java 1.6.0, vô ích .. – zvisofer

3

Dựa trên câu trả lời @zvisofer, tôi thấy guilty piece of code trong BufferedLineReaderInputStream:

@Override 
public int readLine(final ByteArrayBuffer dst) 
     throws MaxLineLimitException, IOException { 
    if (dst == null) { 
     throw new IllegalArgumentException("Buffer may not be null"); 
    } 
    if (!readAllowed()) return -1; 

    int total = 0; 
    boolean found = false; 
    int bytesRead = 0; 
    while (!found) { 
     if (!hasBufferedData()) { 
      bytesRead = fillBuffer(); 
      if (bytesRead == -1) { 
       break; 
      } 
     } 
     int i = indexOf((byte)'\n'); 
     int chunk; 
     if (i != -1) { 
      found = true; 
      chunk = i + 1 - pos(); 
     } else { 
      chunk = length(); 
     } 
     if (chunk > 0) { 
      dst.append(buf(), pos(), chunk); 
      skip(chunk); 
      total += chunk; 
     } 
     if (this.maxLineLen > 0 && dst.length() >= this.maxLineLen) { 
      throw new MaxLineLimitException("Maximum line length limit exceeded"); 
     } 
    } 
    if (total == 0 && bytesRead == -1) { 
     return -1; 
    } else { 
     return total; 
    } 
} 

Điều tốt nhất để làm sẽ là để báo cáo lỗi nhưng đây là cách khắc phục, một chút bẩn nhưng nó làm việc tốt

Tạo lớp org.apache.james.mime4j.io.BufferedLineReaderInputStream trong dự án

của bạn Thay thế phương pháp public int readLine(final ByteArrayBuffer dst) bởi một này:

@Override 
public int readLine(final ByteArrayBuffer dst) 
     throws MaxLineLimitException, IOException { 
    if (dst == null) { 
     throw new IllegalArgumentException("Buffer may not be null"); 
    } 
    if (!readAllowed()) return -1; 

    int total = 0; 
    boolean found = false; 
    int bytesRead = 0; 
    while (!found) { 
     if (!hasBufferedData()) { 
      bytesRead = fillBuffer(); 
      if (bytesRead == -1) { 
       break; 
      } 
     } 

     int chunk; 
     int i = indexOf((byte)'\r'); 
     if (i != -1) { 
      found = true; 
      chunk = i + 2 - pos(); 
     } else { 
      i = indexOf((byte)'\n'); 
      if (i != -1) { 
       found = true; 
       chunk = i + 1 - pos(); 
      } else { 
       chunk = length(); 
      } 
     } 
     if (chunk > 0) { 
      dst.append(buf(), pos(), chunk); 
      skip(chunk); 
      total += chunk; 
     } 
     if (this.maxLineLen > 0 && dst.length() >= this.maxLineLen) { 
      throw new MaxLineLimitException("Maximum line length limit exceeded"); 
     } 
    } 
    if (total == 0 && bytesRead == -1) { 
     return -1; 
    } else { 
     return total; 
    } 
} 

Thưởng thức cả tệp unix và dos :)

+0

Mã này khiến 5 lần thử nghiệm không thành công (một trong số đó là lỗi). Tôi đoán rằng nó sẽ thất bại nếu bạn có '\ r' không theo sau bởi '\ n' – zvisofer

+0

Có, sửa chữa của tôi có thể được cải thiện tôi đoán, xử lý các trường hợp khi \ r là một mình – ToYonos

+0

sử dụng: 'byte [] microsoftSucks = { (byte) '\ r', (byte) '\ n'}; ' 'int i = indexOf (microsoftSucks);' Sửa 3 thử nghiệm nhưng hai vẫn không thành công – zvisofer

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