2014-11-29 5 views
5

Я скачал mime4j 0.8.0 снимок с subversion и построил его с помощью maven. Соответствующие ящики, которые я сгенерировал, можно найти here.Mime4j: DefaultMessageBuilder не удается разобрать содержимое mbox

Теперь я пытаюсь разобрать a toy mbox file от mime4j тест.

Я использую это sample code. Кратко:

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()); 
} 

Выход:

Сообщение нуль Прислал: нуль To: Null Null

сообщение, отправленное: нуль To: нуль

Сообщение null Отправлено: null Кому: null

Сообщение нуль Прислал: нуль To: Null Null

сообщение, отправленное: нуль To: нуль

Найдено 5 сообщений

Есть действительно 5 сообщений, но почему все поля ноль?

+0

Не могли бы вы просто распечатать необработанное сообщение в цикле, чтобы убедиться, что оно правильно построено? 'System.out.println (message);' – ToYonos

ответ

2

Я нашел проблему.

DefaultMessageBuilder не удается разобрать файлы mbox, у которых есть разделитель строк окна \r\n. При замене их разделителем строк UNIX \n работает синтаксический анализ.

Это критическая проблема, так как файлы mbox, загруженные с Gmail, используют \r\n.

+0

Возможно, вы захотите опубликовать запрос на изменение для проекта apache james. Мой опыт общения с сообществом там хорош. –

1

Я загрузил ваши файлы jar, пример кода, на который вы указали, и образец файла mbox, на который вы указали, скомпилировал образец (без изменений) и провел его против образца файла mbox.

Он работал как ожидалось (поля содержат ожидаемые данные, а не нули). Это на Mac с Java 1.6_0_65, а также с 1.8.0_11

Выход был следующим:

$ ява -cp:. Апач-mime4j-ядро-0.8.0-SNAPSHOT. баночка: апач-mime4j-дом-0.8.0-SNAPSHOT.jar: апач-mime4j-Mbox-итератор-0.8.0-SNAPSHOT.jar IterateOverMbox mbox.rlug.txt

сообщение Din окна ма горшок, гам LINUX NU ma pot conecta (la ZAPP) Отправлено: [email protected] Кому: [[email protected]]

Сообщение Re: RH 8.0 boot floppy Прислал: [email protected] To: [[email protected]]

Сообщение Qmail тузд virtualusers + SSL + аутентификации SMTP + pop3 Переданные по: [email protected] To: [rlug @ lug.ro]

сообщения Re: Din окна м горшок, гам LINUX NU ма горшок CONECTA (ла ZAPP) Прислал: [email protected] To: [[email protected]]

Сообщение Проблема LSTP - решена Отправлено: [email protected] To: [rlug @ lug.ро]

Найдено 5 сообщений Совершено в: 108 Milis

+0

Это не работает для меня на двух машинах Windows. Я попробую другую ОС – zvisofer

+0

также пробовал с java 1.6.0, безрезультатно .. – zvisofer

3

основе @zvisofer ответа, я нашел guilty piece of code в 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; 
    } 
} 

Лучше всего сделать было бы сообщить об ошибке, но здесь это исправить, немного грязный, но это работает прекрасно

Создание класса org.apache.james.mime4j.io.BufferedLineReaderInputStream в проекте

Заменить метод public int readLine(final ByteArrayBuffer dst) по этому:

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

Наслаждайтесь файлами unix и dos :)

+0

Этот код вызывает сбой 5 тестов сборки (одна из них - ошибка). Я предполагаю, что он не сработает, если у вас есть «\ r», за которым не следует «\ n» – zvisofer

+0

Да, мое исправление может быть улучшено, я думаю, обрабатывая случай, когда \ r один – ToYonos

+0

, используя: 'byte [] microsoftSucks = { (byte) '\ r', (byte) '\ n'}; ' ' int i = indexOf (microsoftSucks); ' Исправления 3 теста, но два по-прежнему не работают – zvisofer