您可以关闭最外层的流,实际上您不需要保留所有包装的流,您可以使用Java 7 try-with-resources。
try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
new GZIPOutputStream(new FileOutputStream(createdFile)))) {
// write to the buffered writer
}
如果您订阅了 YAGNI,或者您不需要它,则应该只添加实际需要的代码。你不应该添加你认为你可能需要的代码,但实际上并没有做任何有用的事情。
举个例子,想象一下,如果你不这样做,可能会出错,会有什么影响?
try (
OutputStream outputStream = new FileOutputStream(createdFile);
GZIPOutputStream gzipOutputStream = new GZIPOutputStream(outputStream);
OutputStreamWriter osw = new OutputStreamWriter(gzipOutputStream);
BufferedWriter bw = new BufferedWriter(osw)
) {
// ...
}
让我们从FileOutputStream开始,它调用来完成所有实际工作。open
/**
* Opens a file, with the specified name, for overwriting or appending.
* @param name name of file to be opened
* @param append whether the file is to be opened in append mode
*/
private native void open(String name, boolean append)
throws FileNotFoundException;
如果未找到该文件,则没有要关闭的基础资源,因此关闭它不会有任何区别。如果该文件存在,它应该抛出一个FileNotFoundException。因此,仅通过尝试从这条线关闭资源没有任何好处。
您需要关闭文件的原因是文件成功打开,但稍后会收到错误。
让我们看一下下一个流GZIPOutputStream
有些代码可以引发异常
private void writeHeader() throws IOException {
out.write(new byte[] {
(byte) GZIP_MAGIC, // Magic number (short)
(byte)(GZIP_MAGIC >> 8), // Magic number (short)
Deflater.DEFLATED, // Compression method (CM)
0, // Flags (FLG)
0, // Modification time MTIME (int)
0, // Modification time MTIME (int)
0, // Modification time MTIME (int)
0, // Modification time MTIME (int)
0, // Extra flags (XFLG)
0 // Operating system (OS)
});
}
这将写入文件的标头。现在,如果您能够打开文件进行写入,但无法向其写入8个字节,那将是非常不寻常的,但是让我们想象一下,这种情况可能会发生,并且我们之后不会关闭该文件。如果未关闭文件,会发生什么情况?
你不会得到任何未刷新的写入,它们将被丢弃,在这种情况下,没有成功写入流的字节,无论如何,此时都没有缓冲。但是一个没有关闭的文件不会永远存在,相反,FileOutputStream有
protected void finalize() throws IOException {
if (fd != null) {
if (fd == FileDescriptor.out || fd == FileDescriptor.err) {
flush();
} else {
/* if fd is shared, the references in FileDescriptor
* will ensure that finalizer is only called when
* safe to do so. All references using the fd have
* become unreachable. We can call close()
*/
close();
}
}
}
如果您根本不关闭文件,它无论如何都会关闭,只是不会立即关闭(就像我说的,留在缓冲区中的数据将以这种方式丢失,但此时没有任何数据)
不立即关闭文件的后果是什么?在正常情况下,您可能会丢失一些数据,并且可能会用完文件描述符。但是,如果你有一个系统,你可以创建文件,但你不能写任何东西到它们,你有一个更大的问题。也就是说,很难想象为什么你反复尝试创建这个文件,尽管你失败了。
OutputStreamWriter和BufferedWriter都不会在其构造函数中抛出IOException,因此不清楚它们会导致什么问题。在BufferedWriter的情况下,你可以得到一个OutOfMemoryError。在这种情况下,它将立即触发GC,正如我们所看到的,无论如何都会关闭文件。