I/O 입출력, Buffer의 close()의 중요성

may_yun·2022년 10월 13일
0
post-custom-banner

무시했다가 3시간 순삭 close()

발생한 문제

19039건의 CSV 대용량 파일 읽어옴 -> 파싱 -> 객체화 -> 파일생성(.sql)-> 가공한 데이터 파일에 쓰기

  • 파일 쓰는 과정에서 읽어온 데이터의 일부만 작성되는 문제 발생
  • 정상적으로 종료
//디버그 부분
List<String> dbData = new ArrayList<>();
        for (Hospital hospital : hospitals) {
            String makeStr = String.format("(\'%s\',\'%s\',\'%s\',\'%s\',%d,\'%s\',\'%s\'),\n"
                    , hospital.getId()
                    , hospital.getAddress()
                    , hospital.getDistrict()
                    , hospital.getCategory()
                    , hospital.getEmergencyRoom()
                    , hospital.getName()
                    , hospital.getSubdivision());
            dbData.add(makeStr);
        }
        System.out.println();
        write.writeFile(dbData, reprocessData);


해결

close();

  • close의 주기능은 연관된 리소스 해제 (사용한 시스템 자원을 반납하고 스트림 닫음)
  • resource leak : 스트림 리소스 부족 현상 방지
  • IO는 프로그램의 메모리에 상주하는 데이터가 아니라 하드 디스크에서 사용하는 다른 리소스이기 때문에 반드시 close를 해야한다
  • 이전 코드
public void writeFile(List<String> objs, String filename) throws IOException {
        BufferedWriter bw = new BufferedWriter(new FileWriter(filename));

        for (String obj : objs) {
            bw.append(obj);
        }

    }
  • 해결
public void writeFile(List<String> objs, String filename) throws IOException {
        BufferedWriter bw = new BufferedWriter(new FileWriter(filename));

        for (String obj : objs) {
            bw.append(obj);
        }
        bw.close();
    }

파일에 입출력(read&write)이 끝나면 close()를 써줘야 합니다.
'왜 저장이 안되는가?'를 생각해보면 확실한 저장의 끝이 나지 않았기 때문이라 생각됩니다.
이는 byte[]로 길이를 지정한 방식 역시 마찬가지입니다.
write()를 여러 번 해서 저장할 수도 있는 일이니 당연히 바로 저장하지 않을 것입니다.
(buffered는 바로 저장하지 않고 데이터를 모아서 읽거나 쓰기 때문에 문제의 구간이 전부 써지지 않았던게 아닐까 싶습니다)

읽기의 경우 파일에서는 문제가 잘 발생하지 않지만 네트워크 메세지를 받을 때는 문제가 생길 수 있습니다.
만약 A가 B에게 데이터를 보낸다면, 어떤 것을 기준으로 한 마디라 생각해야 할까요?
null(혹은 \0)이 방법이 될 수 있겠지만 이는 연결이 완전히 끊겼을 때 사용되기 때문에 사용할 수 없습니다.
그렇다면 방법은 close()입니다.

profile
개발 일지
post-custom-banner

0개의 댓글