在重构工作中,我发现如果我使用“ 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'时,问题就来了。
那么这是否意味着我的套接字应该一直保持打开状态?我从非技术角度知道,关闭套接字是不合适的,因为我将通过套接字编写消息。但是我试图了解这是否将来会导致内存泄漏。
此致
答案 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