Определите, был ли открытый файл изменен в C - PullRequest
8 голосов
/ 25 декабря 2011

Есть ли способ определить, был ли файл open изменен в POSIX? В частности, как я могу реализовать is_modified() ниже?

FILE *f = fopen("myfile", "r+");

// do various things with f

if (is_modified(f))
    foo(f);

Чтобы обеспечить некоторый контекст, я пишу модуль на C, который для каждого файла должен хранить свой хэш в таблице. Интерфейс предоставляет оболочки для fopen() и fclose(), и хеширование может быть выполнено, когда файл закрыт. Я нашел несколько подходов для этого, но ни один из них не является настолько эффективным, чистым или защищенным от ошибок, как мне бы хотелось:

  • Вычисляет хэш каждого файла, открытого для записи.
  • fflush(f) и проверьте, изменилась ли временная метка.
  • Обеспечьте обертки вокруг fwrite(), fprintf() и т. Д.

Есть предложения?

Ответы [ 3 ]

6 голосов
/ 25 декабря 2011

http://rosettacode.org/wiki/File_modification_time#POSIX_utime.28.29

Вы можете проверить новейшую модификацию по сравнению с последней модификацией с помощью функции stat ().

3 голосов
/ 25 декабря 2011

вы также можете использовать систему уведомлений kqueue для получения уведомлений, когда кто-то изменяет файл, а затем сделать недействительными / перезагрузить ваши хеш-записи

человек 2 kqueue

http://blog.julipedia.org/2004/10/example-of-kqueue.html

3 голосов
/ 25 декабря 2011

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

Обратите внимание, что современный POSIX ( POSIX 2008 ) предоставляет struct stat элементы времени:

  • struct timespec st_atim - метка времени последнего доступа к данным.
  • struct timespec st_mtim - метка времени последнего изменения данных.
  • struct timespec st_ctim - Отметка времени последнего изменения статуса файла.

Они обеспечивают наносекундное разрешение для времени модификации.Вполне вероятно, что по причинам обратной совместимости существуют такие макросы, как:

#define st_atime st_atim.tv_sec
#define st_mtime st_mtim.tv_sec
#define st_ctime st_ctim.tv_sec

, хотя AFAICS, стандарт POSIX, не требует этого.Однако имена st_Xtime использовались с начала (Unix) времени - Версия 7 Unix с 1978 года и, возможно, раньше - поэтому системы захотят сохранить компиляцию старого кода, а макросы, подобные тем, которые обеспечивают умеренно безболезненный способделать это.

...