Java关闭InputStream和OutputStream的正确方法举例
由于 IO 需要您处理需要正确关闭的流、通道和文件描述符,因此Java开发人员处理它们很不舒服。正因为如此,许多Java程序员从不费心做清理工作,懒惰地做工作而忽略任何事情真的很容易。对于从未使用C或C++进行系统编程的程序员来说,这种习惯更加明显。
要将此类持有的文件描述符作为其有限资源释放并用于套接字连接和文件处理,必须关闭流。严重的资源泄漏也可能导致文件描述符异常。
让我们看看在Java不使用任何第三方库将文件从一个目录复制到另一个目录的代码。
Java
import java.io.*;
class Main {
public static void main(String args[])
throws FileNotFoundException
{
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream("input.txt");
fos = new FileOutputStream("output.txt");
// code for reading from input stream and
// writing to output stream }
}
finally {
try {
// careful to close streams in finally
// block, but it’s not complete
if (fis != null)
fis.close();
if (fos != null)
fos.close();
}
catch (IOException e) {
System.out.println(
"Failed to close streams");
}
}
}
}
Java
import java.io.*;
class Main {
public static void main(String args[])
throws FileNotFoundException
{
InputStream is = null;
OutputStream os = null;
try {
is = new FileInputStream(
"../input/fxrates.txt");
os = new FileOutputStream(
"../output/fxrates.txt");
// remaining code
}
finally {
try {
if (is != null)
is.close();
}
catch (IOException e) { /* handle */
}
try {
if (os != null)
os.close();
}
catch (IOException e) { /*handle */
}
}
}
}
大多数代码都不错,甚至比许多Java程序员还要好。但它有一个错误,可能导致Java程序中的资源泄漏。如果输入流的 close() 方法将抛出异常,则输出流将不会被关闭,即如果 fis.close() 抛出异常,则 fos.close() 甚至不会执行。这意味着 OutputStream 持有的文件描述符永远不会释放,从而导致Java程序中的资源泄漏。这并不罕见。
这是在Java中关闭 InputStream 和 OutputStream 的正确方法:
Java
import java.io.*;
class Main {
public static void main(String args[])
throws FileNotFoundException
{
InputStream is = null;
OutputStream os = null;
try {
is = new FileInputStream(
"../input/fxrates.txt");
os = new FileOutputStream(
"../output/fxrates.txt");
// remaining code
}
finally {
try {
if (is != null)
is.close();
}
catch (IOException e) { /* handle */
}
try {
if (os != null)
os.close();
}
catch (IOException e) { /*handle */
}
}
}
}
如果 is.close() 抛出一个 IOException,这段代码不会调用 os.close() 失败,这将保证 OutputStream 保存的文件描述符被释放。