2013-09-28 3 views
0

Почему это, если мы читаем файл с fread() и не включаем fclose для закрытия той же самой ссылки на файл но все же это работает.Функция fclose в c, Почему fread() работает, но не fwrite(), если вы вызываете fclose для обработчика файлов

Однако, если мы забыли включить fclose после fwrite, то это не сработает.i.e. нет записи в файле.

ответ

5

fread(), как следует из названия, считывает данные из файла. Логически, он не может вернуться до тех пор, пока он фактически не прочитает данные (не сохранит их в указанном вами буфере) или не сообщит об ошибке. Как только fread() вернется, вы можете использовать данные.

fwrite(), с другой стороны, может проходить через несколько уровней буферизации, в библиотеке времени выполнения C, в ОС и в других местах. fwrite() возвращается, когда обрабатывается ваши данные и записывается ... где-то. Нет никакой гарантии, что он фактически записан в физический файл, пока вы не сбросите его (fflush(outfile);) или не закроете его (fclose(outfile);). Как только fwrite() вернется, вы можете делать то, что вам нравится, с данными, которые вы ему передали (они были скопированы), но это все, что вы можете предположить.

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

(На самом деле, я думаю, что есть некоторые случаи, когда данные не могут физически прибыть в файле, даже после того, как fclose() или fflush().)

1

Доступ к файлу буферизирован. Когда вы выполняете fread(), он не может вернуться до тех пор, пока фактические данные не будут прочитаны, но если вы выполните fwrite(), тогда он может вернуться после размещения записанных данных в буфер файла, но перед тем, как записать его в основной файл.

Побочный эффект fclose() является промывка файлов буферов - вы можете также использовать fflush() после fwrite() для достижения того же эффекта.

0

Поскольку операция чтения должна, очевидно, завершена после того, как функция fread вернулся - имея на самом деле читать данные в вашем буфере являются одним из постусловий fread, в противном случае вы не могли быть уверены, что можете сделать что-нибудь полезное с данными в буфере после звонка fread .

fwrite, вместо этого, может (и будет) выполнять буферизацию записи - он будет накапливать данные в своем приватном буфере, прежде чем передавать их в операционную систему, чтобы фактически записать их в файл; это возможно (и удобно), поскольку в отношении вашей программы эта вещь полностью прозрачна: данные уже хранятся в каком-то другом буфере, если вы читаете назад из того же потока, вы найдете там свои данные, и все же вы получаете улучшения производительности от кеширования. Тем не менее, если вам нужны ваши данные, чтобы немедленно перейти к ОС, вы можете использовать fflush.

Кстати, даже если вы не звоните fclose сразу же, стандарт гарантирует, что в случае нормального завершения программы потоки автоматически закрываются, и, следовательно, их содержимое очищается.


  1. Кстати, есть вместо сценариев, в которых полезно получить данные, только если он доступен, или для начала операции чтения и проверить позже, если данные были на самом деле читать - и именно поэтому операционные системы предоставляют неблокируемые и асинхронные функции ввода-вывода.
Смежные вопросы