潜在的输出资源泄漏¶
ID: java/output-resource-leak
Kind: problem
Security severity:
Severity: warning
Precision: high
Tags:
- efficiency
- correctness
- resources
- external/cwe/cwe-404
- external/cwe/cwe-772
Query suites:
- java-security-and-quality.qls
如果 Writer
或 OutputStream
的子类打开用于写入但后来没有正确关闭,可能会导致资源泄漏。
建议¶
确保始终关闭资源以避免资源泄漏。请注意,由于异常,最安全的做法是在 finally
块中正确关闭资源。(但是,对于 CharArrayWriter
、StringWriter
和 ByteArrayOutputStream
的子类,这没有必要。)
对于 Java 7 或更高版本,建议使用 try-with-resources
语句声明实现 java.lang.AutoCloseable
的资源,以便它们隐式关闭。
示例¶
在以下示例中,资源 bw
已打开但未关闭。
public class CloseWriter {
public static void main(String[] args) throws IOException {
BufferedWriter bw = new BufferedWriter(new FileWriter("C:\\test.txt"));
bw.write("Hello world!");
// ...
}
}
在以下示例中,资源 bw
在 try
块中打开,并在 finally
块中关闭。
public class CloseWriterFix {
public static void main(String[] args) throws IOException {
BufferedWriter bw = null;
try {
bw = new BufferedWriter(new FileWriter("C:\\test.txt"));
bw.write("Hello world!");
}
finally {
if(bw != null)
bw.close(); // 'bw' is closed
}
// ...
}
}
请注意,如果外部表达式的构造函数可能抛出异常,则使用Writer
或OutputStream
的嵌套类实例创建表达式是不安全的。在以下示例中,OutputStreamWriter
可能会抛出异常,在这种情况下,内部的FileOutputStream
不会关闭。
public class CloseWriterNested {
public static void main(String[] args) throws IOException {
OutputStreamWriter writer = null;
try {
// OutputStreamWriter may throw an exception, in which case the ...
writer = new OutputStreamWriter(
// ... FileOutputStream is not closed by the finally block
new FileOutputStream("C:\\test.txt"), "UTF-8");
writer.write("Hello world!");
}
finally {
if (writer != null)
writer.close();
}
}
}
在这种情况下,需要将内部表达式分配给一个局部变量,并单独关闭,如下所示。
public class CloseWriterNestedFix {
public static void main(String[] args) throws IOException {
FileOutputStream fos = null;
OutputStreamWriter writer = null;
try {
fos = new FileOutputStream("C:\\test.txt");
writer = new OutputStreamWriter(fos);
writer.write("Hello world!");
}
finally {
if (writer != null)
writer.close(); // 'writer' is closed
if (fos != null)
fos.close(); // 'fos' is closed
}
}
}
参考资料¶
IBM developerWorks: Java 理论与实践:良好的维护实践.
Java 教程:带资源的 try 语句.
常见弱点枚举:CWE-404.
常见弱点枚举:CWE-772.