`
sunnodbird
  • 浏览: 32864 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

JavaMail中Folder is not open及OutOfMemory 错误解决办法

    博客分类:
  • java
阅读更多
[size=x-small]  1  Folder is not open[/size]

    最近要做一个邮件收取的东东,功能类似于QQ邮箱中的“其他邮箱”。于是考虑用javamail来实现,查了一些相关的资料,动手写了一个邮箱收取的程序,但是在运行时,在邮箱邮件比较多的情况下,大概每次在收取大概5分钟左右,就会报下面的异常:


        java.lang.IllegalStateException: Folder is not Open
        at com.sun.mail.pop3.POP3Folder.checkOpen(POP3Folder.java:422)
        at com.sun.mail.pop3.POP3Folder.close(POP3Folder.java:193)


       很是郁闷,屡试不爽,每次都会报,在网上google了半天,也没有找到相关的解决办法,最后自己摸索,终于把这个问题解决了。就是在每次读取一个folder时,先判断是否close,如果close就在重新打开一次,这样就解决了,详见下面的代码:


        
Message message[] = folder.getMessages();
        System.out.println("收件箱总数: " + message.length);
        for (int i = 0; i < message.length; i++) {   
             if(!message[i].getFolder().isOpen()) //判断是否open
            	message[i].getFolder().open(Folder.READ_WRITE) //如果close,就重新open  
            printMessage(message[i]);
         }
           


  注意上面的两行注释,每次for循环打开一个新的message时,先判断和这个message里面的folder是否是close的,如果close,就重新打开。后面的printmessage是自已封装的一个方法,对每封邮件进行处理的函数。 这样,就可以解决Folder is not open异常了。


  2  OutOfMemory 异常

   用上面的方法解决了folder is close的异常了,可是在收阅邮件中,如果含有大量的附件,并且在时间较长的情况下,又会报OutOfMemory 异常,很郁闷!遂google相关资料,知道原因是,每次读完一份邮件后,javamail会自动的把该邮件加到cache中,邮件量比较大,在含有大量附件,肯定会报内存溢出错误。但是解决办法没找到,不过其中有一篇文章提到了解决办法,就是修改javamail的源文件中的POP3Folder.java类,让每封邮件读完后,别自动的往缓存中添加,修改后,在重新编译成class,这样是可以解决,但是要改javamail原生的代码,总感觉不太好,应该还有更好的解决办法,不到万不得已,最好不要改原生代码,于是研读javamail APi,终于,在一个角落看到了一个方法POP3Message.invalidate(true);  api如下:

  invalidate
public void invalidate(boolean invalidateHeaders)Invalidate the cache of content for this message object, causing it to be fetched again from the server the next time it is needed. If invalidateHeaders is true, invalidate the headers as well.

Parameters:
invalidateHeaders - invalidate the headers as well?


   啥意思,如果是true,就每次不往缓存中添加内容,false还会添加,默认为false的。这时候答案出来了,原来javamail的开发者早就考虑了这一点,呵呵,于是在程序中添加了这一句,在收取邮件时,上百封邮件,含有大量的附近,中途再没出现过异常。代码见下方:

         Message message[] = folder.getMessages();
        System.out.println("收件箱总数: " + message.length);
        for (int i = 0; i < message.length; i++) {  
             if(!message[i].getFolder().isOpen())
            	message[i].getFolder().open(Folder.READ_WRITE);
            printMessage(message[i]);            

            POP3Message)message[i]).invalidate(true); // 每封邮件读取完后,设置不往cache中添加

            }   






这样文件就解决了。。。。。
如有疑问或书写错误的,请跟帖!或QQ:231901209
分享到:
评论
4 楼 sunnodbird 2014-03-07  
lirui_andy 写道
兄台,POP3Message.invalidate(true)的意思是使缓存失效,这样再读取该message时,会重新从服务器上下载,并不是你说的自动清除缓存。



小弟才疏学浅。。。佩服!
3 楼 lirui_andy 2012-08-20  
兄台,POP3Message.invalidate(true)的意思是使缓存失效,这样再读取该message时,会重新从服务器上下载,并不是你说的自动清除缓存。

2 楼 cucuberboy 2011-12-23  
非常好,这两个问题都一直在困扰我,终于知道答案了
1 楼 fuanyu 2011-11-02  
看你的问题。怎么我发现我的javamail 没有  POP3Message.invalidate(true); // 每封邮件读取完后,设置不往cache中添加 没有这个方法了。你是用哪一个版本?

相关推荐

Global site tag (gtag.js) - Google Analytics