아메리카노가 그렇게 맛있답니다 여러분

사실 자바에서 입출력을 처음 배울 때 마주하게 되지만 다들 무시하는 문구가 하나 있는데 바로 close() 메서드 관련 문구입니다.


[import 안됐다는 error문구 다음으로 보게 되는 warning문구가 이게 아닐까 싶습니다]


이 문구에 대해 검색하면 대부분 한 가지만 말합니다. 'Resource Leak을 방지!'

물론 틀린 것은 아니죠. 위 설명에서도 대놓고 관련 설명을 해주니까요. 조금 더 설명해보자면 main()메서드에서 Scanner를 호출한 것이 아니라면 닫히긴 할 겁니다. 왜냐하면 바인딩이 풀리면서 GC(Garbage Collector)가 알아서 수거하거든요. 아쉽게도 main()에 있다면 그땐 정말 프로그램 종료 이전까지 영원한 누수가 발생하므로 아주 조금 문제가 존재할 수 있습니다.


그런데 이번에 말할 close()는 이 부분이 아닙니다.

입출력과 관련된 stream에서 close()를 설명하려 합니다. 사실 모든 부분에서 테스트하고 쓰는 글이 아닌지라 파일 입출력에 한해서만 설명을 하고자 합니다.

만약 파일에 데이터를 쓰고자 한다면 무식하게는 OutputStream을 깡으로 쓰는 사람도 있겠고, 조금 속도를 고려하면 Buffered를 쓰는 사람도 있을 것입니다. 어느 쪽이든, 파일에 입출력(read&write)이 끝나면 close()를 써줘야 합니다.

너무 당연한 소리인지도 모르겠지만 한동안 파일을 읽는 것만 했지, 쓰는 일을 한 적이 없어 잊어버렸던 내용입니다.

'왜 저장이 안되는가?'를 생각해보면 확실한 저장의 끝이 나지 않았기 때문이라 생각됩니다.

이는 byte[]로 길이를 지정한 방식 역시 마찬가지입니다. write()를 여러 번 해서 저장할 수도 있는 일이니 당연히 바로 저장하지 않을 것입니다.

쓰기는 납득이 가는데 읽기는 왜 문제가 생길까요? 읽기의 경우 파일에서는 문제가 잘 발생하지 않지만 네트워크 메세지를 받을 때는 문제가 생길 수 있습니다.

만약 A가 B에게 데이터를 보낸다면, 어떤 것을 기준으로 한 마디라 생각해야 할까요? null(혹은 \0)이 방법이 될 수 있겠지만 이는 연결이 완전히 끊겼을 때 사용되기 때문에 사용할 수 없습니다. 그렇다면 방법은 close()입니다. 실제로 웹 데이터를 주고 받는 프로그램을 만들 때 문제가 발생한 적이 있습니다. 웹페이지는 일반적으로 페이지를 요청함과 동시에 favicon이라는 아이콘을 요청합니다. 두 번의 request가 발생하게 되는데 close()를 하지 않으면 두 번째 request를 읽을 수 없습니다. 데이터가 왔다는 것은 알지만 읽을 수 있는지 상태를 알려주는 ready()가 false가 되는 일이 발생합니다.

여튼, close()는 중요합니다.