가장 바깥 쪽 스트림을 닫을 수 있습니다. 실제로 모든 스트림을 랩핑 할 필요는 없으며 Java 7 try-with-resources를 사용할 수 있습니다.
try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
new GZIPOutputStream(new FileOutputStream(createdFile)))) {
// write to the buffered writer
}
YAGNI 또는 you-aint-gonna-need-it에 가입 한 경우 실제로 필요한 코드 만 추가해야합니다. 필요하다고 생각되는 코드를 추가해서는 안되지만 실제로는 유용한 기능이 없습니다.
이 예를 들어 보지 않으면 어떻게 될 수 있으며 어떤 영향을 미칠지 상상해보십시오.
try (
OutputStream outputStream = new FileOutputStream(createdFile);
GZIPOutputStream gzipOutputStream = new GZIPOutputStream(outputStream);
OutputStreamWriter osw = new OutputStreamWriter(gzipOutputStream);
BufferedWriter bw = new BufferedWriter(osw)
) {
// ...
}
open
모든 실제 작업을 수행하기 위해 호출 하는 FileOutputStream으로 시작할 수 있습니다.
/**
* 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를 즉시 트리거하여 어쨌든 파일을 닫습니다.