CodeQL 文档

潜在的输出资源泄漏

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

点击查看 CodeQL 仓库中的查询

如果 WriterOutputStream 的子类打开用于写入但后来没有正确关闭,可能会导致资源泄漏。

建议

确保始终关闭资源以避免资源泄漏。请注意,由于异常,最安全的做法是在 finally 块中正确关闭资源。(但是,对于 CharArrayWriterStringWriterByteArrayOutputStream 的子类,这没有必要。)

对于 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!");
		// ...
	}
}

在以下示例中,资源 bwtry 块中打开,并在 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
		}
		// ...
	}
}

请注意,如果外部表达式的构造函数可能抛出异常,则使用WriterOutputStream的嵌套类实例创建表达式是不安全的。在以下示例中,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
		}
	}
}

参考资料

  • ©GitHub, Inc.
  • 条款
  • 隐私