Mam plik dziennika zapisywany przez inny proces, który chcę obserwować pod kątem zmian. Za każdym razem, gdy nastąpi zmiana, chciałbym wczytać nowe dane, aby je trochę przetworzyć.
Jak najlepiej to zrobić? Miałem nadzieję, że będzie jakiś haczyk z biblioteki PyWin32. Znalazłem tę win32file.FindNextChangeNotification
funkcję, ale nie mam pojęcia, jak poprosić ją o obejrzenie określonego pliku.
Jeśli ktoś zrobiłby coś takiego, byłbym bardzo wdzięczny za to, jak ...
[Edytuj] Powinienem wspomnieć, że szukałem rozwiązania, które nie wymaga odpytywania.
[Edytuj] Przekleństwa! Wygląda na to, że to nie działa na zmapowanym dysku sieciowym. Domyślam się, że Windows nie „słyszy” żadnych aktualizacji pliku, tak jak na dysku lokalnym.
strace
monitorującewrite
Odpowiedzi:
Czy przeglądałeś już dokumentację dostępną na stronie http://timgolden.me.uk/python/win32_how_do_i/watch_directory_for_changes.html ? Jeśli potrzebujesz go tylko do pracy w systemie Windows, drugi przykład wydaje się być dokładnie tym, czego chcesz (jeśli zamienisz ścieżkę katalogu na plik z plikiem, który chcesz oglądać).
W przeciwnym razie odpytywanie będzie prawdopodobnie jedyną opcją niezależną od platformy.
Uwaga: nie wypróbowałem żadnego z tych rozwiązań.
źródło
Czy próbowałeś użyć Watchdog ?
źródło
easy_install
? Czek. Darmowa licencja? Sprawdzić . Rozwiązuje problem na dużych platformach? Sprawdzić . Popieram tę odpowiedź. Tylko uwaga: przykład na stronie projektu nie działa od razu po wyjęciu z pudełka. Zamiast tego użyj tego na ich githubie .Jeśli odpytywanie jest dla Ciebie wystarczające, po prostu obserwuję, czy zmieniają się statystyki pliku „zmodyfikowanego czasu”. Aby to przeczytać:
(Należy również pamiętać, że natywne rozwiązanie zdarzenia zmiany systemu Windows nie działa we wszystkich okolicznościach, np. Na dyskach sieciowych).
źródło
if self._cached_stamp is not None
.Jeśli chcesz rozwiązania wieloplatformowego, sprawdź QFileSystemWatcher . Oto przykładowy kod (niezanieczyszczony):
źródło
watchdog
PySide
do tego zamiastPyQt
do tak małego użytku.Nie powinien on działać w systemie Windows (może z cygwinem?), Ale dla użytkownika unixa powinieneś użyć wywołania systemowego „fcntl”. Oto przykład w Pythonie. Jest to w większości ten sam kod, jeśli chcesz go napisać w C (te same nazwy funkcji)
źródło
Sprawdź pyinotify .
inotify zastępuje dnotify (z wcześniejszej odpowiedzi) w nowszych wersjach systemu Linux i umożliwia monitorowanie na poziomie pliku, a nie na poziomie katalogu.
źródło
Po trochę włamania do skryptu Tima Goldena mam następujące, które wydają się działać całkiem dobrze:
Prawdopodobnie przydałoby się to przy sprawdzaniu większej ilości błędów, ale po prostu oglądając plik dziennika i wykonując na nim pewne przetwarzanie przed wyrzuceniem go na ekran, działa to dobrze.
Dziękujemy wszystkim za wkład - świetne rzeczy!
źródło
Aby obejrzeć pojedynczy plik z odpytywaniem i minimalnymi zależnościami, oto w pełni rozwinięty przykład oparty na odpowiedzi Deestana (powyżej):
źródło
watch_file
i tworzyć_cached_stamp
listy oraz iterować je w pętli for. Nie bardzo dobrze skaluje się do dużej liczby plikówcall_func_on_change()
zostanie uruchomiona przy pierwszym uruchomieniulook()
, ale następnie_cached_stamp
zostanie zaktualizowana, więc nie zostanie uruchomiona ponownie, dopóki wartośćos.stat(self.filename).st_mtime. _cached_stamp
zmian nie zostanie wprowadzona._cached_stamp
w konstruktorze, jeśli nie chceszcall_func_on_change()
być wywoływany przy pierwszym uruchomieniuself.call_func_on_change(self) def custom_action(): watcher = Watcher(watch_file, custom_action())
Ale to nie działało. Akcja została wywołana tylko podczas pierwszej iteracji: Plik zmieniony tak, zmieniony Plik zmieniony Plik zmieniony Plik zmieniony Zaczął działać, gdy zachowałem * argumenty i nazwał go:watcher = Watcher(watch_file, custom_action)
Nie mogę się zastanawiać, dlaczego?Sprawdź moją odpowiedź na podobne pytanie . Możesz wypróbować tę samą pętlę w Pythonie. Ta strona sugeruje:
Zobacz także pytanie tail () plik z Pythonem .
źródło
Najprostszym rozwiązaniem jest dla mnie narzędzie watchdog
Od https://pypi.python.org/pypi/watchdog Mam teraz proces, który wyszukuje pliki sql w katalogu i wykonuje je w razie potrzeby.
źródło
Skoro używasz Pythona, możesz po prostu otworzyć plik i nadal czytać z niego wiersze.
Jeśli odczytany wiersz nie jest pusty , przetwarzasz go.
Być może brakuje Ci, że możesz nadal dzwonić
readline
do EOF. W takim przypadku po prostu zwróci pusty ciąg znaków. A kiedy coś zostanie dołączone do pliku dziennika, odczyt będzie kontynuowany od miejsca, w którym się zatrzymał, zgodnie z potrzebami.Jeśli szukasz rozwiązania wykorzystującego zdarzenia lub określoną bibliotekę, określ to w swoim pytaniu. W przeciwnym razie myślę, że to rozwiązanie jest w porządku.
źródło
Oto uproszczona wersja kodu Kendera, która wydaje się robić tę samą sztuczkę i nie importuje całego pliku:
źródło
Jest to kolejna modyfikacja skryptu Tima Goldana, która działa na typach unixowych i dodaje prostego obserwatora do modyfikacji plików za pomocą dict (file => time).
użycie: dowolnaNazwa.py ścieżka_do_katalogu_do_watch
źródło
Jak widać w artykule Tima Golden'a , wskazanym przez Horsta Gutmanna , WIN32 jest stosunkowo złożony i obserwuje katalogi, a nie pojedynczy plik.
Chciałbym zasugerować zajrzenie do IronPython , który jest implementacją Pythona .NET . Dzięki IronPython możesz korzystać ze wszystkich funkcji .NET - w tym
Który obsługuje pojedyncze pliki z prostym interfejsem Event .
źródło
To jest przykład sprawdzania pliku pod kątem zmian. Taki, który może nie jest najlepszym sposobem na zrobienie tego, ale z pewnością jest to krótka droga.
Przydatne narzędzie do ponownego uruchamiania aplikacji po wprowadzeniu zmian w źródle. Zrobiłem to podczas gry z pygame, dzięki czemu mogę zobaczyć efekty, które pojawiają się natychmiast po zapisaniu pliku.
Podczas używania w grze pygame upewnij się, że elementy w pętli „while” są umieszczone w pętli gry, czyli jako aktualizacja lub cokolwiek innego. W przeciwnym razie twoja aplikacja utknie w nieskończonej pętli i nie zobaczysz aktualizacji swojej gry.
Na wypadek, gdybyś chciał ponownie uruchomić kod, który znalazłem w sieci. Oto jest. (Nie dotyczy pytania, choć może się przydać)
Baw się dobrze, gdy elektrony robią to, co chcesz.
źródło
.st_mtime
zamiast.st_size
byłoby bardziej niezawodnym i równie krótkim sposobem na zrobienie tego, chociaż PO wskazał, że nie chce tego robić przez ankietę.źródło
Oto przykład ukierunkowany na oglądanie plików wejściowych, które zapisują nie więcej niż jedną linię na sekundę, ale zwykle o wiele mniej. Celem jest dołączenie ostatniego wiersza (najnowszego zapisu) do określonego pliku wyjściowego. Skopiowałem to z jednego z moich projektów i właśnie usunąłem wszystkie niepotrzebne wiersze. Musisz wypełnić lub zmienić brakujące symbole.
Oczywiście obejmująca klasa QMainWindow nie jest ściśle wymagana, tj. możesz użyć samego QFileSystemWatcher.
źródło
Możesz także użyć prostej biblioteki o nazwie repyt , oto przykład:
źródło
Wygląda na to, że nikt nie opublikował fswatch . Jest wieloplatformowym obserwatorem systemu plików. Po prostu zainstaluj, uruchom i postępuj zgodnie z instrukcjami.
Użyłem go z programami python i golang i to po prostu działa.
źródło
powiązane rozwiązanie @ 4Oh4 płynna zmiana listy plików do obejrzenia;
źródło
Najlepszym i najprostszym rozwiązaniem jest użycie pygtail: https://pypi.python.org/pypi/pygtail
źródło
Nie znam żadnej funkcji specyficznej dla systemu Windows. Możesz spróbować uzyskać skrót MD5 pliku co sekundę / minutę / godzinę (w zależności od tego, jak szybko go potrzebujesz) i porównać go z ostatnim skrótem. Kiedy różni się, wiesz, że plik został zmieniony i czytasz najnowsze wiersze.
źródło
Spróbowałbym czegoś takiego.
Pętla sprawdza, czy są nowe linie od ostatniego odczytu pliku - jeśli istnieje, jest on odczytywany i przekazywany do
functionThatAnalisesTheLine
funkcji. Jeśli nie, skrypt czeka 1 sekundę i ponawia proces.źródło