Chciałbym otrzymać powiadomienie, gdy plik zostanie zmieniony w systemie plików. Nie znalazłem nic poza wątkiem, który sonduje właściwość lastModified File i najwyraźniej to rozwiązanie nie jest optymalne.
Dzięki za wszystkie odpowiedzi. Ponieważ moje potrzeby są małe (potrzebuję tylko przeładować zmieniony plik właściwości w mojej aplikacji internetowej… głównie dlatego, że ponowne uruchamianie całej aplikacji internetowej jest trochę powolne), pozostanę przy modelu ankiety. Przynajmniej teraz wiem, że nie ma prostego rozwiązania dla tych przypadków.
cheng81
14
Tylko uwaga. Kiedy rozwiązaliśmy ten problem, zanim odkryliśmy, że duże pliki zwykle przychodzą powoli, a mechanizm odpytywania często odkrywał nowy lub zmieniony plik, zanim został w pełni zapisany. Aby rozwiązać ten problem, przyjęto rozwiązanie typu „dwa kęsy”. Ankieter zauważył, że plik uległ zmianie, ale nie powiadomił systemu o nowym / zmienionym pliku, dopóki nie wyglądał tak samo przez dwie ankiety, tj. Nie ustabilizował się. Wyleczono wiele błędnych plików.
Steve Powell
1
Nawiasem mówiąc, Tomcat ma ten problem podczas upuszczania dużych plików WAR do folderu webapps ze zdalnych źródeł i robi to przez długi czas.
John Rix
Odpowiedzi:
21
Na niskim poziomie jedynym sposobem modelowania tego narzędzia jest odpytywanie wątków w katalogu i obserwowanie atrybutów pliku. Ale możesz użyć wzorców, aby opracować adapter dla takiego narzędzia.
Na przykład serwery aplikacji j2ee, takie jak Tomcat i inne, mają funkcję automatycznego ładowania, która powoduje ponowne uruchomienie aplikacji po zmianie deskryptora wdrażania lub zmianie klasy serwletu.
Możesz korzystać z bibliotek z takich serwerów, ponieważ większość kodu tomcat jest wielokrotnego użytku i open source.
To już nie jest prawdą w Javie 7: istnieje teraz interfejs API, który może podłączyć się do usług powiadamiania systemu operacyjnego: blogs.oracle.com/thejavatutorials/entry/ ...
Arnout Engelen
Ten interfejs API jest wysoce nieodpowiedni i nie zapewnia powiadomień o zdarzeniach związanych z zamknięciem plików w systemie Linux. Tak więc, biorąc pod uwagę prosty przypadek, gdy plik jest zamknięty, skopiowanie go do innego katalogu nie działa.
binarytemple_picsolve
117
Napisałem już wcześniej monitor pliku dziennika i odkryłem, że wpływ odpytywania atrybutów pojedynczego pliku kilka razy na sekundę na wydajność systemu jest w rzeczywistości bardzo mały.
widzę przykłady jako obserwację katalogu, ale co z pojedynczym plikiem?
Archimedes Trajano
@ArchimedesTrajano Interfejs API powiadamia o zmianie pliku w katalogu. Wyzwalane zdarzenie zawiera nazwę pliku, który się zmienił. Możesz więc obsługiwać zdarzenia dla określonego pliku lub plików i ignorować inne.
Istnieje biblioteka o nazwie jnotify, która otacza inotify w systemie Linux i obsługuje również okna. Nigdy go nie używałem i nie wiem, jakie jest dobre, ale powiedziałbym, że warto spróbować.
Działa doskonale i jest super prosty w użyciu. Używam inotify od wielu lat. Jest szybki, stabilny i niezawodny
oᴉɹǝɥɔ
8
Java commons-io ma FileAlterationObserver . wykonuje odpytywanie w połączeniu z FileAlterationMonitor. Podobny do commons VFS. Zaletą jest to, że ma znacznie mniej zależności.
edycja: mniej zależności nie jest prawdą, są one opcjonalne dla VFS. Ale używa pliku java zamiast warstwy abstrakcji VFS.
Czy mógłbyś być bardziej szczegółowy lub zamieścić link do dokumentacji? Nie mogę znaleźć niczego na ten temat ...
Luciano,
Wydaje się, że to pakiet java.nio.file. Zobacz samouczek .
David L.
4
Uruchamiam ten fragment kodu za każdym razem, gdy czytam plik właściwości, w rzeczywistości czytam plik tylko wtedy, gdy został zmodyfikowany od czasu ostatniego czytania. Mam nadzieję, że to komuś pomoże.
privatelong timeStamp;privateFile file;privateboolean isFileUpdated(File file ){this.file = file;this.timeStamp = file.lastModified();if(this.timeStamp != timeStamp ){this.timeStamp = timeStamp;//Yes, file is updatedreturntrue;}//No, file is not updatedreturnfalse;}
Podobne podejście zastosowano w Log4J FileWatchdog.
Jeśli chcesz rozstać się z pewnymi pieniędzmi, JNIWrapper jest przydatną biblioteką z pakietem Winpack, będziesz w stanie uzyskać zdarzenia systemu plików w niektórych plikach. Niestety tylko okna.
W przeciwnym razie uciekanie się do kodu natywnego nie zawsze jest złą rzeczą, zwłaszcza gdy najlepszą ofertą jest mechanizm odpytywania, a nie zdarzenie natywne.
Zauważyłem, że operacje systemu plików Java mogą być powolne na niektórych komputerach i mogą łatwo wpływać na wydajność aplikacji, jeśli nie są dobrze obsługiwane.
Możesz również rozważyć Apache Commons JCI (Java Compiler Interface). Chociaż wydaje się, że ten interfejs API koncentruje się na dynamicznej kompilacji klas, zawiera również klasy w swoim API, które monitorują zmiany plików.
Istnieje komercyjna biblioteka na różnych pulpitach do oglądania plików i folderów o nazwie JxFileWatcher. Można go pobrać stąd:
http://www.teamdev.com/jxfilewatcher/
Sondowanie ostatnio zmodyfikowanej właściwości pliku jest jednak prostym, ale skutecznym rozwiązaniem. Po prostu zdefiniuj klasę rozszerzającą my FileChangedWatcheri zaimplementuj onModified()metodę:
Podobnie jak w przypadku innych odpowiedzi, oto jak to zrobiłem za pomocą File, Timer i TimerTask, aby uruchomić to jako sondowanie wątku w tle w ustalonych odstępach czasu.
Odpowiedzi:
Na niskim poziomie jedynym sposobem modelowania tego narzędzia jest odpytywanie wątków w katalogu i obserwowanie atrybutów pliku. Ale możesz użyć wzorców, aby opracować adapter dla takiego narzędzia.
Na przykład serwery aplikacji j2ee, takie jak Tomcat i inne, mają funkcję automatycznego ładowania, która powoduje ponowne uruchomienie aplikacji po zmianie deskryptora wdrażania lub zmianie klasy serwletu.
Możesz korzystać z bibliotek z takich serwerów, ponieważ większość kodu tomcat jest wielokrotnego użytku i open source.
źródło
Napisałem już wcześniej monitor pliku dziennika i odkryłem, że wpływ odpytywania atrybutów pojedynczego pliku kilka razy na sekundę na wydajność systemu jest w rzeczywistości bardzo mały.
Java 7, jako część NIO.2, dodała WatchService API
źródło
Używam API VFS z Apache Commons, oto przykład, jak monitorować plik bez większego wpływu na wydajność:
DefaultFileMonitor
źródło
Istnieje biblioteka o nazwie jnotify, która otacza inotify w systemie Linux i obsługuje również okna. Nigdy go nie używałem i nie wiem, jakie jest dobre, ale powiedziałbym, że warto spróbować.
źródło
Java commons-io ma FileAlterationObserver . wykonuje odpytywanie w połączeniu z FileAlterationMonitor. Podobny do commons VFS. Zaletą jest to, że ma znacznie mniej zależności.
edycja: mniej zależności nie jest prawdą, są one opcjonalne dla VFS. Ale używa pliku java zamiast warstwy abstrakcji VFS.
źródło
„Więcej funkcji NIO” ma funkcję monitorowania plików, której implementacja zależy od bazowego systemu operacyjnego. Powinien być w JDK7.
źródło
java.nio.file
. Zobacz samouczek .Uruchamiam ten fragment kodu za każdym razem, gdy czytam plik właściwości, w rzeczywistości czytam plik tylko wtedy, gdy został zmodyfikowany od czasu ostatniego czytania. Mam nadzieję, że to komuś pomoże.
Podobne podejście zastosowano w Log4J
FileWatchdog
.źródło
Możesz słuchać zmian plików za pomocą FileReader. Plz zobacz poniższy przykład
źródło
Jeśli chcesz rozstać się z pewnymi pieniędzmi, JNIWrapper jest przydatną biblioteką z pakietem Winpack, będziesz w stanie uzyskać zdarzenia systemu plików w niektórych plikach. Niestety tylko okna.
Zobacz https://www.teamdev.com/jniwrapper .
W przeciwnym razie uciekanie się do kodu natywnego nie zawsze jest złą rzeczą, zwłaszcza gdy najlepszą ofertą jest mechanizm odpytywania, a nie zdarzenie natywne.
Zauważyłem, że operacje systemu plików Java mogą być powolne na niektórych komputerach i mogą łatwo wpływać na wydajność aplikacji, jeśli nie są dobrze obsługiwane.
źródło
Możesz również rozważyć Apache Commons JCI (Java Compiler Interface). Chociaż wydaje się, że ten interfejs API koncentruje się na dynamicznej kompilacji klas, zawiera również klasy w swoim API, które monitorują zmiany plików.
Przykład: http://commons.apache.org/jci/usage.html
źródło
Spring Integration zapewnia ładny mechanizm do oglądania katalogów i plików: http://static.springsource.org/spring-integration/reference/htmlsingle/#files . Jestem pewien, że jest to platforma wieloplatformowa (używałem jej na komputerach Mac, Linux i Windows).
źródło
Istnieje komercyjna biblioteka na różnych pulpitach do oglądania plików i folderów o nazwie JxFileWatcher. Można go pobrać stąd: http://www.teamdev.com/jxfilewatcher/
Możesz również zobaczyć to w akcji online: http://www.teamdev.com/jxfilewatcher/onlinedemo/
źródło
Sondowanie ostatnio zmodyfikowanej właściwości pliku jest jednak prostym, ale skutecznym rozwiązaniem. Po prostu zdefiniuj klasę rozszerzającą my
FileChangedWatcher
i zaimplementujonModified()
metodę:źródło
Podobnie jak w przypadku innych odpowiedzi, oto jak to zrobiłem za pomocą File, Timer i TimerTask, aby uruchomić to jako sondowanie wątku w tle w ustalonych odstępach czasu.
źródło