2011-12-25 3 views
8

파일이 POSIX에서 수정되었는지 확인하는 방법이 있습니까? 더 구체적으로, 아래에 is_modified()을 어떻게 구현할 수 있습니까?열린 파일이 C로 수정되었는지 확인

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

// do various things with f 

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

일부 컨텍스트를 제공하기 위해 모든 파일에 해시를 테이블에 저장해야하는 모듈을 C 언어로 작성했습니다. 인터페이스는 fopen()fclose()에 대한 래퍼를 제공하며 파일이 닫힐 때 해싱을 수행 할 수 있습니다. 이 작업을 수행하는 방법은 여러 가지가 있지만 효율적인 방법, 깨끗한 방법 또는 오류가없는 방법은 내가 좋아할만한 것입니다.

  • 쓰기 위해 열린 모든 파일의 해시를 계산합니다.
  • fflush(f) 타임 스탬프가 변경되었는지 확인하십시오. 등
  • 제공 래퍼 주위 fwrite(), fprintf(),

어떤 제안이?

+1

사람이 당신의 해시 항목을 다시로드/무효화 한 후 누군가가 파일을 변경할 때 알림을받을 kqueue 알림 시스템을 사용하고 있습니다 당신은 하나라면 그 파일을 엽니 다. 단순히 파일을 쓸 지 여부를 계속 추적하지 않는 이유는 무엇입니까? –

+0

추상화. 이것은 클라이언트가 원하는대로 작동 할 수있는 파일 핸들을 제공하는 모듈입니다. 표준 라이브러리 함수를 사용하여 열린 파일에서 작동하는 다른 코드의 큰 부분을 수정하고 싶지 않습니다. – nccc

+0

다른 프로세스가 파일을 동시에 수정할 수 없도록하려면 [파일 잠금] (http://en.wikipedia.org/wiki/File_locking)을 살펴보십시오. – jweyrich

답변

6

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

당신은 합계() 함수를 마지막으로 수정에 대한 최신 수정을 확인할 수 있습니다. 파일을 열 때 파일을 닫고, 두 가지를 비교하려고 할 때 다시

+1

그건 아주 간단한 해결책이지만 경쟁 조건에 취약합니다. 수정 시간을 얻은 후이를 비교하고 조치를 취하기 전에 파일이 이미 다른 프로세스/스레드에 의해 변경되었을 수 있습니다. 그럼에도 불구하고 +1. – jweyrich

+0

전적으로 동의합니다. 최소한의 시간을 기다리려면 sleep()을 수행 할 수 있습니다. 필자의 의견으로는 위와 같이 설계된 문제에 대한 차선책입니다. – nmjohn

+2

이미 파일 디스크립터를 사용할 수 있기 때문에'stat()'대신'fstat()'를 사용할 것을 권장합니다. –

3

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 이름은 1978 년부터 유닉스 버전 (Unix)이 시작된 이래로 사용되었고 아마도 이전 버전이므로 시스템에서 오래된 코드를 컴파일하고 매크로를 유지하려고합니다. 그래서.

+0

불행히도 파일이 열려있는 동안'st_mtime'과 다른 멤버들은 업데이트되지 않습니다. 그래서,이 해결책은'fclose(); stat();'너무. – nccc

+0

업데이트가 예약됩니다 (변경 사항이있는 경우 fflush() d) ... 그리고 정말로 걱정이된다면 O_xSYNC 옵션 중 하나를 파일 설명자에 적용 할 수 있습니다. 이 프로그램은 (적절한 헤더와 함께) 데모; MacOS X 10.7.2를 테스트했지만 POSIX 시스템에서 예상되는 결과입니다 :'int main (void) {struct stat s1, s2; char name [] = "zzz"; FILE * fp; fstat (fileno (fp), &s1);) put ('x', fp); fflush (fp); fstat (fileno (fp) fp), &s2); printf ("t1 % ld; t2 % ld \ n", (긴) s1.st_mtime, (긴) s2.st_mtime); fclose (fp); ' –

+0

예,'fflush()'는 아마도 inode를 참조하기 때문에 타임 스탬프를 업데이트 할 것입니다. 이것은 가능한 한 멀리까지 진행될 것 같아요. 커널은 파일이 더럽지 만 어쨌든 보이지 않습니다. – nccc

3
+0

재미 있습니다. : a) _every_ write가 이벤트를 생성한다는 것을 의미합니다. b)'kevent()'블록 이후로 적어도 두 개의 쓰레드가 필요하다. 옳은? – nccc

+0

a) 예,하지만 특정 기간 동안 이벤트를 대기열에 넣은 다음 언제든지 상환 할 수 있으며 대량으로 다른 스레드로 보냅니다. b) 예, 이벤트를 기다리는 두 번째 스레드가 필요합니다. – jackdoe

관련 문제