5

我已经下载mime4j了 0.8.0 快照subversion并使用maven. 我生成的相关 jar 可以在这里找到。

现在我尝试从测试中解析一个玩具 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 条消息,但为什么所有字段都为空?

4

3 回答 3

3

根据@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文件:)

于 2014-12-03T12:09:53.843 回答
2

我发现了问题。

DefaultMessageBuilder无法解析具有 windows 行分隔符的 mbox 文件\r\n。当用 UNIX 行分隔符替换它们时\n,解析工作。

这是一个关键问题,因为 mbox 文件是从Gmail使用\r\n.

于 2014-12-02T13:40:35.137 回答
1

我下载了您的 jar 文件、您指向的示例代码和您指向的示例 mbox 文件,编译了示例(没有更改)并针对示例 mbox 文件运行它。

它按预期工作(字段包含预期数据,而不是空值)。这是在带有 Java 1.6_0_65 和 1.8.0_11 的 Mac 上

输出如下:

$ 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) Sent by: rlug-bounce@lug.ro To: [rlug@lug.ro]

消息回复:RH 8.0 启动软盘 发送者:rlug-bounce@lug.ro 至:[rlug@lug.ro]

Message Qmail mysql virtualusers +ssl + smtp auth +pop3 Sent by: rlug-bounce@lug.ro To: [rlug@lug.ro]

Message Re: Din windows ma pot, din LINUX NU ma pot conecta (la ZAPP) Sent by: rlug-bounce@lug.ro To: [rlug@lug.ro]

消息 LSTP 问题 - 已解决 发送者:rlug-bounce@lug.ro 收件人:[rlug@lug.ro]

找到 5 条消息 完成于:108 英里

于 2014-12-01T14:04:22.443 回答