2013-01-21 5 views
29

이 코드아파치 commons-io IOUtils.close Quietly를 사용하는 것이 안전합니까?

BufferedWriter bw = new BufferedWriter(new FileWriter("test.txt")); 
    try { 
     bw.write("test"); 
    } finally { 
     IOUtils.closeQuietly(bw); 
    } 

안전 여부가요? BufferedWriter를 닫으면 버퍼가 기본 스트림으로 플러시되고 오류로 인해 실패 할 수 있습니다. 그러나 IOUtils.closeQuietly API는 모든 예외가 무시 될 것이라고 말합니다.

IOUtils.close Quietly로 인해 데이터 손실이 눈에 띄지 않을 수 있습니까?

+5

[try-with-resources] (http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html) 문은 'IOUtils.closeQuietly' 사용에 대한 대부분의 요구 사항을 제거합니다. . – lyomi

+1

좋은 답변이지만이 기능은 Java 7의 새로운 기능입니다. Java 6을 사용하여 어떤 이유로 든 (예 : 이전 Android 버전) 멈추게되면 'closeQuietly()'가 계속됩니다. –

답변

34

코드는 closeQuietly()의 자바 독에 관한 다음과 같아야합니다

BufferedWriter bw = null; 

try { 
    bw = new BufferedWriter(new FileWriter("test.txt")); 
    bw.write("test"); 
    bw.flush(); // you can omit this if you don't care about errors while flushing 
    bw.close(); // you can omit this if you don't care about errors while closing 
} catch (IOException e) { 
    // error handling (e.g. on flushing) 
} finally { 
    IOUtils.closeQuietly(bw); 
} 

closeQuietly()는 일반적으로 사용하는 대신 폐쇄 가능한 직접 close()를 호출하기위한 것이 아닙니다. 의도 된 유스 - 케이스는 finally 블록 내부를 클로즈업하기위한 것이다. 모든 에러 핸들링은 그 전에 수행되어야한다.

즉, close() 또는 flush()이라는 호출 중에 예외에 대응하려면 정상적인 방법으로 처리해야합니다. 최종 블록에 closeQuietly()을 추가하면 닫기가 보장됩니다. 플러시가 실패하고 try-block에서 close가 호출되지 않은 경우.

+0

bw.close()가 불필요하다고 생각합니다. bw.close()는 flush()를 호출합니다. –

+2

@EvgeniyDorofeev 네가 거기에 close()를 남기 만하면됩니다. 그러나 플러시 중에 예외에 대해서만 관심이 있지만 닫히지 않으면 예외를 명시 적으로 플러시해야합니다. 예제를 좀 더 보편적으로 만들기 위해 두 메소드 호출을 작성했습니다. –

+0

그냥 분명히 : bw.close()에 대한 호출을 생략하고 finally {} 절에서 bw가 여전히 올바르게 닫힐 수 있습니다. 이 방법을 사용하면'bw.close()'중에 에러를 알 수 있습니다. –

5

이론상 가능하지만 close()가 실패한 것을 본 적이 없다고 말할 수는 없습니다. 일반적으로 오류가 발생하면 파일 열기와 같은 이전 IO 작업이 먼저 실패합니다. IOException을 무시하지 않는 닫기를 작성할 수는 있지만, 실패한 try/catch 블록에있는 경우 예외의 진정한 원인을 망칠 수 있습니다. 당신이 원하는 무엇

이 같은입니다 (대부분의 경우 과잉 인)

try { 
    // write to bw. 
    bw.close(); // throw IOException if an error occurs. 

} finally { 
    // don't clobber a previous IOException 
    IOUtils.closeQuietly(bw); 
} 
+2

잘못 사용하고 있습니다 - IOUtils.closeQuietly()는 Closable에서 직접 close()를 호출하는 대신 일반적인 용도로 사용하지 않습니다. 그 의도 된 사용 사례는 리소스 누출을 피하기 위해 finally 블록 내부에서 close()가 호출되도록하는 것입니다. 모든 오류 처리 (로깅, 예외 래핑 및 재 처리)는 먼저 수행해야합니다. Fabian의 대답 –

+0

@ JarekPrzygódzki 마지막 시간 IOException을 가까이에서 보았습니까? –

+0

거의 발생하지 않지만 Closeable 또는 {Input, Output} 스트림 뒤에 무엇이 있는지 결코 알지 못합니다. 그리고 예외를 조용히하면 거의 좋지 않습니다. –

7

응용 프로그램이 쓰기 오류없이 성공 여부를 상관하지 않는 한 그것은 너무 오래 안전 다음과 같습니다. 응용 프로그램에서 쓰기 오류를 처리해야하는 경우 buffered data flushed on close이 손실되어 오류가 삼켜 서 안전하지 않습니다.