developer tip

Java InputStream 닫기

copycodes 2020. 11. 20. 09:04
반응형

Java InputStream 닫기


Java InputStreams를 사용할 때 close () 메서드 사용에 대해 몇 가지 질문이 있습니다. 내가보고 읽은 대부분의 개발자로부터 더 이상 필요하지 않을 때 항상 명시 적으로 InputStream에서 close ()를 호출해야합니다. 하지만 오늘 저는 Java 속성 파일을 사용하려고했는데 제가 찾은 모든 예제에는 다음과 같은 내용이 있습니다.

Properties props = new Properties();
try {
    props.load(new FileInputStream("message.properties"));
    //omitted.
} catch (Exception ex) {}

위의 예에서는 InputStream을 사용한 후에는 연결할 수 없기 때문에 명시 적으로 close ()를 호출 할 방법이 없습니다. 대부분의 사람들이 명시 적으로 닫는 것에 대해 말하는 것과 모순되는 것처럼 보이지만 InputStreams의 유사한 사용을 많이 보았습니다. Oracle의 JavaDocs를 읽었으며 Properties.load () 메서드가 InputStream을 닫는 지 여부는 언급하지 않았습니다. 이것이 일반적으로 허용되는지 또는 다음과 같은 작업을 더 선호하는지 궁금합니다.

Properties props = new Properties();
InputStream fis = new FileInputStream("message.properties");
try {
    props.load(fis);
    //omitted.
} catch (Exception ex) {
    //omitted.
} finally {
    try {
        fis.close();
    } catch (IOException ioex) {
        //omitted.
    }
}

어느 쪽이 더 좋고 / 또는 더 효율적입니까? 아니면 정말 중요합니까?


속성 자습서 의 예제는 FileInputStream로드 후 명시 적으로 닫히 므로 load메서드가 책임을지지 않는다고 가정하는 것이 안전하다고 생각합니다 .

// create and load default properties
Properties defaultProps = new Properties();
FileInputStream in = new FileInputStream("defaultProperties");
defaultProps.load(in);
in.close();

그냥 참조를 위해, 나는 확인 아파치 하모니 의 구현 속성을 , 그리고 그것을 수행 하지 로드에 가까운 스트림을.


Properties 클래스는 LineReader에서 입력 스트림을 래핑하여 속성 파일을 읽습니다. 입력 스트림을 제공하므로이를 닫는 것은 사용자의 책임입니다.

두 번째 예는 스트림을 처리하는 더 좋은 방법입니다. 다른 사람에게 의존하여 닫지 마십시오.

개선 할 수있는 한 가지 방법은 IOUtils.closeQuietly () 를 사용하는 것입니다.

스트림을 닫습니다. 예 :

Properties props = new Properties();
InputStream fis = new FileInputStream("message.properties");
try {
    props.load(fis);
    //omitted.
} catch (Exception ex) {
    //omitted.
} finally {
    IOUtils.closeQuietly(fis);
}

나는 try-with-resources (적어도 Java 7+의 경우)를 사용합니다.

Properties props = new Properties();

try(InputStream fis = new FileInputStream("message.properties")) {
    props.load(fis);
    //omitted.
} catch (Exception ex) {
    //omitted.
}

close () 호출은 try 블록이 종료 될 때 자동으로 호출되어야합니다.


props.load입력 스트림을 닫는 문서에는 언급되어 있지 않습니다 . 제안한대로 finally 블록에서 입력 스트림을 수동으로 닫아야합니다.

함수가 InputStream. 가비지 수집되지 않은 언어의 메모리와 동일한 규칙이 적용됩니다. 가능하면 스트림을 여는 사람이 스트림을 닫아야합니다. 그렇지 않으면 스트림을 열어 두는 것이 매우 쉽습니다 (함수가 닫을 것이라고 생각하지만 닫히지 않거나 뭔가 ...)


Java 7 이상을 사용하는 경우 다음을 사용할 수 있습니다.

try(InputStream is = new FileInputStream("message.properties")) {
    // ...
}

It looks like the first code sample ends up relying on the finalize method in FileInputStream to actually close the file. I would say your second example is better, even though in both cases the file does get closed.

There are cases like the Byte streams where close does nothing and can be omitted, otherwise I think it's better to explicitly close the file in a finally block. If you open it, you close it.

There is a book on Oracle's site called Java Platform Performance that discusses finalizers in its appendix, it says:

You are almost always better off doing your own cleanup instead of relying on a finalizer. Using a finalizer can also leave behind critical resources that won't be recovered for an indeterminate amount of time. If you are considering using a finalizer to ensure that important resources are freed in a timely manner, you might want to reconsider.


Let me add a little something to other people's answers.

If you can import Apache Commons IO, you could make use of the ever-so-handy AutoCloseInputStreams classes: you wrap your InputStream and then you just use your wrapped instance and it gets automatically closed as soon as the end of input has been reached or when the stream is explicitly closed, whichever comes first.

참고URL : https://stackoverflow.com/questions/3991577/closing-java-inputstreams

반응형