Mime4j: DefaultMessageBuilder не в состоянии проанализировать содержимое mbox
Я скачал mime4j
0.8.0 снимок с subversion
и построил его с maven
, Соответствующие банки, которые я создал, можно найти здесь.
Теперь я пытаюсь разобрать файл игрушки mbox из mime4j
тестовое задание.
Я использую этот пример кода. Кратко:
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());
}
Выход:
Сообщение null Отправлено: null Кому: null
Сообщение null Отправлено: null Кому: null
Сообщение null Отправлено: null Кому: null
Сообщение null Отправлено: null Кому: null
Сообщение null Отправлено: null Кому: null
Найдено 5 сообщений
Сообщений действительно 5, но почему все поля пусты?
3 ответа
Я нашел проблему.
DefaultMessageBuilder
не в состоянии анализировать файлы mbox, которые имеют разделитель строк Windows \r\n
, При замене их на разделитель строк UNIX \n
разбора работает.
Это критическая проблема, так как файлы mbox, загруженные с Gmail
использование \r\n
,
Основываясь на ответе @zvisofer, я нашел виновный кусок кода в 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 файлами:)
Я скачал ваши jar-файлы, пример кода, на который вы указали, и пример файла mbox, на который вы указали, скомпилировал образец (без изменений) и запустил его для файла примера mbox.
Он работал как ожидалось (поля содержали ожидаемые данные, а не нули). Это было на Mac с Java 1.6_0_65, а также с 1.8.0_11
Вывод был следующим:
$ 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
Сообщение Din windows ma pot, din LINUX NU ma pot conecta (la ZAPP) Отправлено: rlug-bounce@lug.ro Кому: [rlug@lug.ro]
Сообщение Re: загрузочная дискета RH 8.0. Отправлено: rlug-bounce@lug.ro Кому: [rlug@lug.ro]
Сообщение Qmail mysql virtualusers +ssl + smtp auth +pop3 Отправлено: rlug-bounce@lug.ro Кому: [rlug@lug.ro]
Сообщение Re: Din windows ma pot, din LINUX NU ma pot conecta (la ZAPP) Отправлено: rlug-bounce@lug.ro Кому: [rlug@lug.ro]
Сообщение LSTP проблема - решена Отправлено: rlug-bounce@lug.ro Кому: [rlug@lug.ro]
Найдено 5 сообщений Сделано в: 108 milis