ifstream을 수동으로 닫아야합니까?


201

close()사용할 때 수동으로 전화해야 std::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()수동으로 전화 해야합니까? 파일을 닫기 위해 RAIIifstream사용 해서는 안 됩니까?

답변:


251

아니

이것이 RAII의 목적입니다. 소멸자가 그 일을하도록하십시오. 수동으로 닫는 데 아무런 해가 없지만 C ++ 방식이 아니며 클래스를 사용하여 C로 프로그래밍합니다.

함수가 끝나기 전에 파일을 닫으려면 항상 중첩 범위를 사용할 수 있습니다.

표준 (27.8.1.5 클래스 템플릿 basic_ifstream) 에서 실제 파일 핸들을 보유 ifstream하는 basic_filebuf멤버 로 구현됩니다 . ifstream 객체가 소멸 될 때 멤버를 소멸자로 호출하도록 멤버로 유지됩니다 basic_filebuf. 그리고 표준 (27.8.1.2)에서 그 소멸자는 파일을 닫습니다.

virtual ˜basic_filebuf();

효과 : class의 객체를 파괴합니다 basic_filebuf<charT,traits>. 전화 close().


4
+1 RAII가 처리한다는 것을 몰랐습니다 ... 매일 새로운 것을 배우는 것 같습니다
TStamper

21
중첩 된 범위를 사용하여 파일을 닫는 것은 완전히 인공적인 것입니다. 파일을 닫으려면 close ()를 호출하십시오.

3
그러나 객체의 수명을 필요한 범위로 제한하면 실수로 닫힌 ifstream에 액세스하지 않을 수 있다고 주장 할 수 있습니다. 그러나 그것은 약간 고안되었습니다.
Eclipse

9
C ++에서 중첩 범위는 거의 필요하지 않습니다. 그것들은 특히 무언가가 던져 질 때 코드의 행동과 관련이 있습니다. 미래의 관리자가 그것들을 제거한다면, 그는 C ++을 잘 모른다.
Elliot Cameron

2
때로는 close()오류 처리를 위해 수동으로 호출 해야합니다.
ks1322

71

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

파일을 닫아야합니까?
다릅니다.

파일이 올바르게 닫히지 않을 경우 발생할 수있는 오류 조건에 관심이 있습니까? setstate(failbit)실패하면 전화를 끊어야합니다. 소멸자는 RAIIclose() 때문에 자동으로 호출 하지만 객체가 더 이상 존재하지 않으므로 페일 비트를 테스트하는 방법을 남기지 않습니다.


14

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


5

아니요, ifstream소멸자가 자동으로 수행합니다 . 수동으로 호출해야하는 유일한 이유는 fstream인스턴스가 오래 지속되는 클래스 인스턴스의 멤버 변수 인 경우와 같이 범위가 넓기 때문입니다.


4
또 다른 이유는 스트림에 예외가 허용되는 경우 파일 닫기 오류를 확인하고 소멸자를 던지는 것을 방지하기위한 것일 수 있습니다.
Daniel Langr

4

소멸자가 작업을 수행하도록 허용 할 수 있습니다. 그러나 RAII 객체와 마찬가지로 수동으로 close를 호출하면 차이가 생길 수 있습니다. 예를 들면 다음과 같습니다.

#include <fstream>

using std::ofstream;

int main() {
  ofstream ofs("hello.txt");
  ofs << "Hello world\n";
  return 0;
}

파일 내용을 씁니다. 그러나:

#include <stdlib.h>

#include <fstream>

using std::ofstream;

int main() {
  ofstream ofs("hello.txt");
  ofs << "Hello world\n";
  exit(0);
}

하지 않습니다. 프로세스가 갑자기 종료되는 드문 경우입니다. 충돌하는 프로세스도 비슷할 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.