2013-04-28 1 views
5

Этот вопрос: How to protect log from application crash? привел меня к другому - что делает std::ofstream::close() на самом деле? Я знаю, что это flush(), и это одно. Но что еще? На самом деле закрытие файла?Что делает std :: ofstream :: close() на самом деле?

Edit: Позвольте мне перефразировать мой вопрос - это ничего физически сделано для фактического файла во время вызова close() или это просто std::ofstream внутренний материал очистки?

ответ

3

Другие, чем промывка буферов пользовательского пространства, т.е. flush(), close(2) вызывается основной файловой-дескриптора. Это зависит от операционной системы, что происходит тогда, но, скорее всего, ничего не происходит с фактическим хранением, занимаемым файлом.

будет Случается, что (если дескриптор файла был последней ссылкой в ​​этом процессе к этому файлу), запись файла, связанная с файлом, удаляется из таблицы открытых файлов процесса. То есть освобождение связанной с процессом памяти ядра.

1

Закрывает файл, связанный с объектом, удаляя его из потока.

Любая ожидающая выходная последовательность записывается в файл.

Если поток в настоящее время не связан ни с одним файлом (то есть, файл с ним не был успешно открыт), вызов этой функции завершается с ошибкой.

Файловая ассоциация потока хранится в буфере внутреннего потока: Внутренне функция вызывает rdbuf() -> close() и устанавливает failbit в случае отказа.

Обратите внимание, что любой открытый файл автоматически закрывается при уничтожении объекта thestream.

От: http://www.cplusplus.com/reference/fstream/ofstream/close/

+0

Я перефразировал свой вопрос, см. Редактирование оригинального сообщения. – NPS

3

Вот трассировка вызовов из документации:


void std::basic_ofstream::close(); 

Эффективно вызывает rdbuf()->close(). Если во время работы возникает ошибка, вызывается setstate(failbit).


std::basic_streambuf<CharT,Traits>* std::basic_ofstream::rdbuf() const; 

Возвращает ассоциативный поток буфера. Если нет связанного буфера потока, возвращается NULL.


std::basic_streambuf фактически наследует std::basic_filebuf, поэтому:


std::basic_filebuf<CharT, Traits>* std::basic_filebuf::close(); 

Если область положить существует (например, файл был открыт для записи), первые звонки overflow(Traits::eof()) писать все в ожидании выхода в файл, включая любые последовательности без сдвига.

Если совсем недавно вызываемая функция, из underflow(), overflow(), seekpos() и seekoff(), был overflow(), затем вызывает std::codecvt::unshift(), возможно, несколько раз, чтобы определить unshift последовательности в соответствии с проникнуто локал, и пишет, что последовательность в файл с overflow(Traits::eof()).

Затем закрывает файл, как если бы он вызывал std::fclose, независимо от того, выполнено или нет какой-либо из предыдущих вызовов.

ПРИМЕЧАНИЕ.close() обычно вызывается через деструктор std::basic_filebuf (который, в свою очередь, как правило, называется по деструктора std::basic_fstream


Прежде всего, мы можем видеть, что это Безразлично» t фактически вызывают flush(), как и ожидалось. Тем не менее, эффект flushing действительно встречается в методе std::basic_filebuf::close(). Кроме того, мы видим, что он по-прежнему немного искажает файл, то есть записывает последовательность без сдвига. происходит тогда, файл просто закрывается.

Обратите внимание на ПРИМЕЧАНИЕ выше: в большинстве случаев вам даже не нужно звонить std::basic_ofstream::close() явно.