2009-04-14 2 views
138

std::ifstream을 사용할 때 수동으로 close()으로 전화해야합니까? 코드의 예를 들어 ifstream을 수동으로 닫아야합니까?

:

std::string readContentsOfFile(std::string fileName) { 

    std::ifstream file(fileName.c_str()); 

    if (file.good()) { 
     std::stringstream buffer; 
     buffer << file.rdbuf(); 
     file.close(); 

     return buffer.str(); 
    } 
    throw std::runtime_exception("file not found"); 
} 

내가 수동으로 file.close()를 호출해야합니까? RAII 파일을 닫으려면 을 사용해야합니까?

답변

182

NO

이 RAII는 소멸자가 일을하자위한 것입니다. 수동으로 닫는 데 아무런 해가 없지만 C++ 방식이 아니며 클래스를 사용하여 C로 프로그래밍됩니다.

함수 종료 전에 파일을 닫으려면 항상 중첩 된 범위를 사용할 수 있습니다.

표준 (27.8.1.5 클래스 템플릿 basic_ifstream)에서 ifstream은 실제 파일 핸들이있는 basic_filebuf 구성원으로 구현됩니다. ifstream 객체가 파괴 될 때 basic_filebuf에있는 소멸자도 호출 할 수 있도록 멤버로 유지됩니다. 표준 (27.8.1.2)에서, 그 소멸자가 파일을 닫을 :

virtual ˜basic_filebuf();

효과 :basic_filebuf<charT,traits> 클래스의 객체를 파괴한다. 전화 close().

+12

+1 - RAII의 의미를 아는 사람 : --) – Milan

+3

+1 RAII에서 처리하는 것을 알지 못했습니다 ... 매일 새로운 무언가를 배울 것 같습니다 – TStamper

+13

파일을 닫는 중첩 범위를 사용하면 완전히 인위적입니다 - 닫으려는 경우 close()를 호출하십시오. –

43

파일을 닫아야합니까?
아니오

파일을 닫으시겠습니까?
에 따라 다릅니다.

파일이 올바르게 닫히지 않을 때 발생할 수있는 오류 조건에 신경 쓰십니까? 실패 할 경우 close 호출은 setstate (failbit)를 호출합니다. 소멸자는 RAII 때문에 자동으로 close()를 호출하지만 객체가 더 이상 존재하지 않으면 실패 비트를 테스트 할 방법을 제공하지 않습니다.

4

아니요,이 작업은 ifstream 소멸자가 자동으로 수행합니다. 수동으로 호출해야하는 유일한 이유는 fstream 인스턴스가 큰 범위를 가지기 때문입니다. 예를 들어 긴 클래스 클래스 인스턴스의 멤버 변수 인 경우입니다.

+0

또 다른 이유는 파일 닫는 오류를 검사하고 예외가 허용되는 경우 소멸자가 throw되는 것을 방지하기 위해서 일 수 있습니다 스트림. –

8

@Martin에 동의합니다. 파일에 쓰면 데이터가 여전히 버퍼에있을 수 있으며 close()이 호출 될 때까지 파일에 기록되지 않을 수 있습니다. 수동으로하지 않고도 오류가 있는지 여부는 알 수 없습니다. 사용자에게 오류를보고하지 않는 것은 매우 나쁜 습관입니다.

관련 문제