Java-SMTP传输器要求SocketOutputStream无限期打开

时间:2018-08-29 11:09:43

标签: java smtp javamail

在重构工作中,我发现如果我使用“ try-with-resources”关闭输出流-我总是从Java的SMTPTransport获得MessagingException。它总是抱怨套接字已关闭。

我确定存在问题的代码是:

try (LineOutputStream los = new LineOutputStream(os);) {
    los.writeln(signatureHeaderLine);
    Enumeration hdrLines = getNonMatchingHeaderLines(ignoreList);
    while (hdrLines.hasMoreElements()) {
        String notIgnoredLine = (String) hdrLines.nextElement();
        los.writeln(notIgnoredLine);
    }

    los.writeln();
    // Send signed mail to waiting DATA command
    os.write(osBody.toByteArray());
    os.flush();
} catch (MessagingException me) {
    // Deal with it
} catch (Exception e) {
    // Deal with it
}

上面的代码是MimeMessage.writeTo(OutputStream, String[])覆盖的一部分,当最终从SMTPTransport调用`issueSendCommand'和'sendCommand'时,问题就来了。

那么这是否意味着我的套接字应该一直保持打开状态?我从非技术角度知道,关闭套接字是不合适的,因为我将通过套接字编写消息。但是我试图了解这是否将来会导致内存泄漏。

此致

1 个答案:

答案 0 :(得分:0)

我相信问题是由于您在ngrx语句之外使用了OutputStream os

try-with-resource语句确保执行try-with-resource块后将关闭所有初始化的AutoClosable资源。在try关闭时,com.sun.mail.util.LineOutputStream OutputStream(传递给其构造函数)也将关闭。 os语句之后对os的任何访问都将对已经关闭的try-with-resource起作用。

编辑,当OutputStream的{​​{1}}方法无效时,会有一个例外。例如OutputStream

  

关闭ByteArrayOutputStream无效。可以在关闭流之后调用此类中的方法,而不会产生IOException。

演示片段

close()

使用ByteArrayOutputStream调用方法private static void demoMethod(OutputStream os) throws IOException { try (LineOutputStream los = new LineOutputStream(os)) { los.writeln("signatureHeaderLine"); los.writeln(); os.write("foo".getBytes()); System.out.println("within try-block"); } catch (Exception e) { System.out.println(e); } os.write("bar".getBytes()); System.out.println("after try-block"); }

demoMethod

提供输出

ByteArrayOutputStream

因此,即使在调用ByteArrayOutputStream os = new ByteArrayOutputStream(); demoMethod(os); 之后也可以使用within try-block after try-block (由try-with-resource代码调用的LineOutputStream.close()隐式调用)。

ByteArrayOutputStream

进行相同操作
close()

引发异常,因为FileOutputStream语句的结尾处的FileOutputStream os = new FileOutputStream("/tmp/dummy.out"); demoMethod(os); 已经结束。

FileOutputStream