2012-11-01 3 views
2

MyOpenedFile이 열려있는 스트림으로 파일을 래핑하는 것이라고 상상해보십시오. 질문에 대한Java 객체에 파괴가 발생하는 명확한 방법이 있습니까?

// method in an Util class 
static void safeClose(MyOpenedFile f) { 
    if (f != null) { 
    try { 
     f.close(); 
    } catch(IOException ex) { /* add logging or console output */ } 
    } 
} 

실제 방법 : 다음 코드 가정

void doSomeFileOperation(...) throws IOException, ... { 
    MyOpenedFile f1 = null; 
    MyOpenedFile f2 = null; 
    try { 

     /* method's "business logic" code beings */ 
     f1 = new MyOpenedFile(...); 
     //do stuff 
     f2 = new MyOpenedFile(...); 
     // do stuff 
     f1.close(); f1 = null; 
     // do stuff with f1 closed 
     f2.close(); f2 = null; 
     // do stuff with f2 closed 
     /* method's "business logic" code ends */ 

    } finally { 
     Util.safeClose(f1); f1 = null; 
     Util.safeClose(f2); f2 = null; 
    } 
} 

지금이 아주 지저분하고, 특히 오류가 발생하기 쉬운입니다 (finally 블록은 매우 어려울 수 있습니다에서 일부 코드는 장치에서 호출하세요 테스트 등). 예를 들어 C++에서 소멸자는 정리 된 포인터 소멸자 또는 직접 호출되는 정리를 처리하고 코드는 훨씬 더 깨끗합니다.

그래서, 비즈니스 로직 코드의 조각 위에 포장 더 나은/더 좋은/청소기 방법은, 그래서 거기에 예외가 전파 얻을하지만 두 파일 f1f2 심지어 경우, 닫히지 (또는 적어도 가까이하는 것은 모두 시도된다 실패)?

좋은 래퍼를 제공하는 Apache Commons와 같은 오픈 소스 라이브러리를 가리키는 답변도 환영합니다.

+0

BTW, 코드 샘플은 실제로 당신이 당신이 그것을 닫기 전에 널 (null) = F1 설정 때문에 파일 핸들 누출의 원인이됩니다 거기에 실수가있다. – Chii

+0

@Chii 아니, 내가 볼 수있는 한. 모든 'null'할당 전에'close' 또는'safeClose' *가 있습니다. – hyde

+0

왜 파일 당'close'를 두 번 호출합니까? (try와 finally에서)? – home

답변

4

파일을 경우 자바 7이 좋은 새로운 기능을 가지고있는

존재하지 않을 수도있는 파일 이름을 포함하는 String의 래퍼입니다. 상태를 유지할 수 있으므로 닫을 필요가 없습니다.

닫으 필요한 자원은 FileInputStream에 또는 BufferedReader로 그리고 당신이 그가 출구를 차단 br whent을 닫습니다

try(BufferedReader br = new BufferedReader(new FileReader(file))) { 

} 

자바 7에서 ARM으로 암시 적으로 다음을 닫을 수 있습니다.

http://www.oracle.com/technetwork/articles/java/trywithresources-401775.html

+1

나는 가장 좋은 시점에 대한 답변을 받아들이고, IMO의 좋은 코드 샘플 (때로는 작음이 아름답습니다)을 사용하여 고마워합니다. 이제 나에게 남아있는 것은 Java7을 실제 환경에서 사용할 수 있는지 알아야합니다. - / – hyde

0

자동으로 내 머리에 오는 옵션은 다음과 같습니다. 파일을 처리하는 코드와 처리를 수행하는 코드를 구분하십시오. 이렇게하면 열리고 닫히고 예외 처리를 처리하는 불쾌한 코드를 캡슐화 할 수 있습니다.

다른 비트는 당신이 가지고있는 샘플 당신은 null로 파일 인스턴스를 설정할 필요가 없습니다 여분의 불필요한 단계

void doSomeFileOperation(...) throws IOException, ... { 
    File f1 = null; 
    File f2 = null; 
    try { 
     f1 = new File(...); 
     f2 = new File(...); 
     // callback to another class/method that does the real work 
    } finally { 
     Util.safeClose(f1); 
     Util.safeClose(f2); 
    } 
} 

많이 않는다는 것입니다. 그들을 사용하려고하면 예외가 발생합니다.

당신이 사용하고있는 객체가 무엇인지 궁금합니다. File Java의 표준 File 클래스에는 close() 메소드가 없습니다.

+0

처음에는 똑같은 생각이 들었지만, 결함은'f1이 닫히는 물건을 다루는 '요구 사항이 더 이상 유지되지 않는다는 것입니다. 두 가지 다른 콜백을 전달해야하므로 문제가 실제로 해결되지 않았습니다. – Chii

+0

예, 정확한 비즈니스 코드에 따라 정리를 최적화 할 수 있습니다. 그러나 이것은 다른 경우에 대한 다른 상용구 코드로 이어 지므로 더 악화 될 수 있습니다. – hyde

1

try 블록이 끝난 후 리소스를 닫을 The try-with-resources Statement을 살펴보십시오.

클래스는 close() 메서드가 없으므로 사용하지 않습니다. 이 경우 자신의 File 클래스가 ARM과 함께 작동하도록 Closeable을 구현해야합니다. 당신은 여기에서 언급 한 바와 같이 (파일 시스템에있는 파일의 표현입니다) 파일을 닫을 필요가없는

try (FileInputStream f1 = new FileInputStream("test1.txt"); 
    FileInputStream f2 = new FileInputStream("test2.txt")) { 
    // Some code 
} catch (FileNotFoundException e) { 
    e.printStackTrace(); 
} catch (IOException e) { 
    e.printStackTrace(); 
} 
+0

'File '것을 지적하면서 클래스 이름을 변경하고 커스텀 클래스 이름의 논리를 설명하는 질문에 주석을 추가했습니다. – hyde

+1

한 알씩, 일반적인 팻말이 너에게 지시하지 않는 것보다 : 나는 그런 종류의 캐치 블럭이 아주 드물게 사용되어야한다고 생각한다. 거의 항상 예외를 잡아서 기록하고 아무 일도없는 것처럼 계속 진행하는 것은 나쁜 생각입니다. 예외를 안전하게 무시할 수 있으면 로깅은 혼란 스럽다. 조치가 취해질 필요가 있다면, 그냥 로깅하는 것 (GUI 응용 프로그램에서 대화 상자를 팝업하는 것) 이상이어야합니다. 대부분의 예외는 전파 될 수 있어야하며 때로는 다른 관련 예외의 원인으로 전파되어야합니다. 로깅은 * 프로그래머가 옳은 일을 확신 할 수 없을 때 주로 유용합니다. – hyde

1

:

Do I need to close files I perform File.getName() on?

난 당신이 파일 스트림/독자에 대한 자세한 내용을 물어 보는 것 같은데요? 당신이 자바의 이전 버전에서 작업하는 경우 http://www.vineetmanohar.com/2011/03/java-7-try-with-auto-closable-resources/

난 그냥 간단이와 계속 것 :

void doSomeFileOperation(...) throws IOException, ... { 
    FileInputStream f1 = null; 
    FileInputStream f2 = null; 
    try { 

    // do stuff 

    } finally { 
    Util.safeClose(f1); 
    Util.safeClose(f2); 
    } 
}