2010-07-29 2 views
6

계속하기 전에 파일이 생성되었는지 확인하려면 다음과 같은 코드를 사용하고 있습니다. 파일이 존재하기 훨씬 전에 파일이 파일 브라우저에 표시되고 있는지 확인합니다. stat에 의해 감지되었습니다 ...이 문제가 있습니까?stat를 사용하여 파일 존재 여부 감지 (천천히?)

//... do something 

struct stat buf; 

while(stat("myfile.txt", &buf)) 
    sleep(1); 

//... do something else 

또는 파일이 있는지 여부를 확인하는 더 좋은 방법이 있습니까?

+0

어떤 파일 브라우저를 : 여기에

은 검사 파일이 이미 존재하는 경우를 inotify를 시계를 설정하고, 그렇지 않으면 그것을 위해 기다리는 C++ 코드 예제입니다? 파일을 쓰고있는 것은 무엇입니까? 파일이 약간 다른 이름으로 쓰여지지 않고 마지막 순간에 이름이 변경되지 않았습니까? –

+0

나는 konqueror를 사용하고 있지만, 돌고래는 stat보다 이전에 알려줍니다. 파일은 내가 작성한 응용 프로그램에 의해 쓰여지고 있으므로, 무엇을 어디에 써야하는지 알고 있습니다. 또한 파일은 프로세스가 완료되었음을 알리기 위해 쓰는 빈 파일입니다. –

+0

이 지연 시간은 얼마나 걸립니까? 마이크로 초 또는 분 단위입니까? 'stat()'가 실제로 존재할 때 파일이 존재 함을 나타내지 못하는 이유가 없어야합니다. 당신이 아직 알아 내지 못했던 다른 것이 여기에 있다고 생각합니다. –

답변

3

"stat"시스템 호출은 파일을 가리키는 여러 개의 하드 링크 나 "inode"번호와 같이 파일에 대한 다른 정보를 수집합니다. "mode"에서 "F_OK"플래그를 지정함으로써 존재 체크를 수행하는 데 사용할 수있는 "액세스"시스템 호출을 볼 수 있습니다.

그러나 코드에 약간의 문제가 있습니다. 그것은 아직 존재하지 않는 파일을 검사 할 때마다 잠깐 프로세스를 잠자기 상태로 만듭니다. 이를 피하기 위해 Jerry Coffin에서 제안한대로 inotify API를 사용해야 만합니다. 대기중인 파일이있을 때 커널이이를 알리기 위해서입니다. inotify는 파일이 이미 있으면 알려주지 않으므로 파일을 만든 직후에 파일을 시청할 때 경쟁 상태가되지 않도록 "액세스"와 "inotify"를 모두 사용해야합니다.

파일이 있는지 확인하는 더 좋고 빠른 방법은 없습니다. 파일 브라우저가이 프로그램이 감지하는 것보다 약간 더 빨리 파일을 표시하면 Greg Hewgill의 이름 바꾸기 아이디어가 실제로 발생합니다.

#include <cstdio> 
#include <cstring> 
#include <string> 

#include <unistd.h> 
#include <sys/inotify.h> 

int 
main() 
{ 
    const std::string directory = "/tmp"; 
    const std::string filename = "test.txt"; 
    const std::string fullpath = directory + "/" + filename; 

    int fd = inotify_init(); 
    int watch = inotify_add_watch (fd, directory.c_str(), 
            IN_MODIFY | IN_CREATE | IN_MOVED_TO); 

    if (access (fullpath.c_str(), F_OK) == 0) 
    { 
     printf ("File %s exists.\n", fullpath.c_str()); 
     return 0; 
    } 

    char buf [1024 * (sizeof (inotify_event) + 16)]; 
    ssize_t length; 

    bool isCreated = false; 

    while (!isCreated) 
    { 
     length = read (fd, buf, sizeof (buf)); 
     if (length < 0) 
      break; 
     inotify_event *event; 
     for (size_t i = 0; i < static_cast<size_t> (length); 
      i += sizeof (inotify_event) + event->len) 
     { 
      event = reinterpret_cast<inotify_event *> (&buf[i]); 
      if (event->len > 0 && filename == event->name) 
      { 
       printf ("The file %s was created.\n", event->name); 
       isCreated = true; 
       break; 
      } 
     } 
    } 

    inotify_rm_watch (fd, watch); 
    close (fd); 
} 
+0

하나의 질문은 수면 (1)과 같은 큰 문제입니다 ... 몇 초의 지연은 문제가 아니며 가장 많이 수면 통화를 추가하는 것으로 예상됩니다. –

+0

아니요, 수면 제거는 여기에서 10 초에서 60 초 정도 지연되는 경우 문제 해결보다는 우수성을 추구하는 것입니다. Greg Hewgill은 NFS와 같은 복제 및 다른 시스템에 대해 올바른 질문을합니다. 그런 것들이 가장 가능성있는 원인입니다. 또한 파일을 만들거나 폴링하는 대신 프로세스가 완료 될 때까지 기다리는 데 사용할 수있는 "waitpid"시스템 호출이 있습니다. –

+0

알림 또는 액세스 함수 호출 후에도 파일이 존재한다는 보장이 없음에도 경쟁 조건이 있습니다. 전화 할 때만. 실제로 파일이 있는지 확인하기위한 테스트는 피해야합니다. 파일에 액세스 할 수 없거나 파일을 사용하는 동안 파일을 잃어 버리면 파일이 있다고 가정하고 대소 문자를 처리해야합니다. 예 1 : 파일은 있지만 액세스 권한이 없습니다. 예 2 : 마운트가 사라지기 때문에 파일이 "사라집니다"(NFS). – Rahly

4

inotify을 사용하면 파일 시스템 변경 (예 : 파일 생성)이 발생할 때 커널이 사용자에게 알릴 수 있습니다. 이것은 파일 브라우저가 파일에 대해 너무 빨리 알기 위해 사용하는 것일 수 있습니다.

1

코드가 파일이 매초 있는지 확인합니다. 대신 inotify을 사용하여 일정을 가져올 수 있습니다.