2010-07-29 14 views
6

Używam kodu jak poniżej, aby sprawdzić, czy plik został utworzony przed kontynuowaniem, rzecz jest plik jest wyświetlany w przeglądarce plików dużo przed tym, jak jest on wykryte przez stat ... czy jest jakiś problem z tym?przy użyciu stat, aby wykryć, czy plik istnieje (wolno?)

//... do something 

struct stat buf; 

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

//... do something else 

alternatywnie czy istnieje lepszy sposób sprawdzenia, czy plik istnieje?

+0

Co pliku? Co pisze plik? Czy jesteś pewien, że plik nie jest zapisywany pod nieco inną nazwą, a następnie zmienia się jego nazwę w ostatniej chwili? –

+0

Używam konquerora, ale delfin powiadamia również moje wcześniejsze niż stat. plik jest pisany przez aplikację, którą napisałem, więc wiem, co i gdzie powinien być zapisany. także, plik jest pustym plikiem, który piszę, aby zasygnalizować, że proces się zakończył. –

+0

Jak długo trwa opóźnienie? Czy jest rzędu mikrosekund, czy minut? Nie powinno być żadnego powodu, dla którego 'stat()' nie wskaże, że plik istnieje, kiedy naprawdę działa. Podejrzewam, że dzieje się tu coś jeszcze, czego jeszcze nie rozpoznaliście. –

Odpowiedz

3

Wywołanie systemowe "stat" zbiera różne informacje o pliku, takie jak na przykład liczba wskazujących go twardych linków lub numer "i-węzła". Możesz rzucić okiem na wywołanie systemowe "dostęp", którego możesz użyć do sprawdzenia istnienia tylko przez określenie flagi "F_OK" w "trybie".

Istnieje jednak mały problem z kodem. Uruchamia proces na sekundę za każdym razem, gdy sprawdza plik, który jeszcze nie istnieje. Aby tego uniknąć, musisz użyć interfejsu API inotify, zgodnie z sugestią Jerry'ego Coffina, aby otrzymać powiadomienie przez jądro, gdy plik, na który czekasz, jest dostępny. Pamiętaj, że inotify nie powiadamia Cię, jeśli plik już istnieje, więc w rzeczywistości musisz użyć zarówno "dostępu", jak i "inotify", aby uniknąć sytuacji wyścigu, gdy zacząłeś oglądać plik tuż po jego utworzeniu.

Nie ma lepszej lub szybszej metody sprawdzania, czy plik istnieje. Jeśli twoja przeglądarka plików nadal pokazuje plik nieco szybciej, niż ten program wykrywa, wtedy pomysł Grega Hewgilla na zmianę nazwy prawdopodobnie ma miejsce.

Oto przykład kodu C++, który konfiguruje inotify zegarek, sprawdza, czy plik już istnieje i czeka na to inaczej: przeglądarkę

#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

jedno pytanie, to sen (1) taki duży problem ... kilka sekund opóźnienia nie jest problemem, a to najbardziej oczekiwałbym od dodania wezwania snu. –

+0

Nie, wyeliminowanie snu jest tylko dążeniem do doskonałości, a nie rozwiązywaniem problemów, jeśli mówimy o opóźnieniu o 10 do 60 sekund. Greg Hewgill zadaje właściwe pytania dotyczące replikacji podobnej do NFS i różnych maszyn. Te rzeczy są najbardziej prawdopodobnymi przyczynami. Istnieje również wywołanie systemowe "waitpid", którego można użyć do oczekiwania na zakończenie procesu, zamiast tworzenia/odpytywania pliku. –

+0

Ma to również warunek wyścigowy polegający na tym, że nie ma gwarancji, że plik istnieje po wywołaniu funkcji powiadomień LUB dostępu. Tylko w czasie połączeń. W rzeczywistości należy unikać testowania, czy plik istnieje. Powinieneś założyć, że plik istnieje i załatwić sprawę, jeśli nie możesz uzyskać do niego dostępu lub stracisz go podczas pracy z nim. Przykład 1: Plik istnieje, ale nie masz dostępu. Przykład 2: Plik "znika", ponieważ uchwyt zniknie (NFS). – Rahly

4

Za pomocą inotify można ustawić jądro, aby powiadamiało użytkownika o zmianie systemu plików (np. Tworzenie pliku). Może to być tak, jak szybko używa twoja przeglądarka plików, aby wiedzieć o pliku.

1

Twój kod sprawdzi, czy plik jest dostępny co sekundę. możesz użyć numeru inotify, aby otrzymać wydarzenie.

Powiązane problemy