티스토리 뷰

Stream 관련 기능을 사용하다 보면 가끔 겪는 증상이다. 

java.io.IOException: Stream Closed
	at java.base/java.io.FileOutputStream.writeBytes(Native Method)
	at java.base/java.io.FileOutputStream.write(FileOutputStream.java:349)
	at java.base/java.io.BufferedOutputStream.write(BufferedOutputStream.java:123)
	at java.base/java.io.FilterOutputStream.write(FilterOutputStream.java:108)

결론부터 얘기하자면 이 오류의 원인내용 그대로 Stream으로 뭘 써야 하는데 이게 닫혀 버렸기 때문이다. 

위와 같은 경우라면 어디에선가 FileOutputStream 객체(fos라고 하자)를 어디에선가 fos.close()를 했을 것이다. 저렇게 명시적으로 close를 해준 경우라면 오류를 조치하기 어렵지 않은데 내가 close를 해준적도 없는데 위와 같은 오류가 나면 많은 생각이 들게 된다. 

 

아래 글은 명시적으로 close 해주는 부분이 없다면 의심해 봐야 할 부분을 예시로 들어 놓은 것이다. 


필자의 경우는 전역변수로 BufferedOutputStream을 놓고 각 메서드에서 이걸 공유해서 써야 하는 상황이 생겼다. 그래서 다음과 같이 코딩을 하니 문제가 되었다. 

private BufferedOutputStream bos = null;
private StringBuilder sb = null;

...

public sampleMethod1() {

try (
    FileOutputStream fos =  new FileOutputStream(this.file);
){
    this.bos = new BufferedOutputStream(fos);
    this.sb = new StringBuilder();
}
...

public sampleMethod2() {

try {
    this.sb.append("append text");
    this.bos.write(this.sb.toString().getBytes("UTF-8"));     //에러발생지점

..

얼마전에 공유한 try-with-resources 를 사용해 FileOutputStream 자원을 sampleMethod1 수행하고 해제하려고 했는데 이게 해제가 되니 BufferedOutputStream도 다음과 같은 상태가 되어 정상적으로 사용할 수 없었다. 

BufferedOutputStream & FileOutputStream

전역으로 BufferedOutputStream를 정의해서 사용한다면 이와 같은 점을 주의하자. 뭐 별로 사용할일은 없겠지만... 이런 상황 뿐만 아니라 자원의 효과적인 관리를 위해서는 위의 코드를 다음과 같이 바꿔서 사용하도록 하자. 

private BufferedOutputStream bos = null;
private StringBuilder sb = null;

...

public sampleMethod1() {

this.bos = new BufferedOutputStream(new FileOutputStream(this.file));
this.sb = new StringBuilder();

...

public sampleMethod2() {

try {
    this.sb.append("append text");
    this.bos.write(this.sb.toString().getBytes("UTF-8"));     //에러발생지점

..

즉 FileOutputStream의 객체를 따로 생성하지 말고 위와 같이 변수로 그냥 값을 넣어서 사용하는 방법이 좋다. 

 

끝!

댓글
최근에 올라온 글
최근에 달린 댓글
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31