Notez comment utiliser WatchService
pour surveiller les changements de dossier et de fichier dans Java.
OS Window 10
Java
java version "1.8.0_151"
Java(TM) SE Runtime Environment (build 1.8.0_151-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode)
Hello World
package sample.watch;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Paths;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.nio.file.Watchable;
import static java.nio.file.StandardWatchEventKinds.*;
import static java.nio.file.WatchEvent.*;
public class Main {
public static void main(String[] args) {
WatchService watcher;
try {
watcher = FileSystems.getDefault().newWatchService();
Watchable path = Paths.get("./build");
path.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
} catch (IOException e) {
e.printStackTrace();
return;
}
while (true) {
WatchKey watchKey;
try {
watchKey = watcher.take();
} catch (InterruptedException e) {
System.err.println(e.getMessage());
return;
}
for (WatchEvent<?> event : watchKey.pollEvents()) {
Kind<?> kind = event.kind();
Object context = event.context();
System.out.println("kind=" + kind + ", context=" + context);
}
if (!watchKey.reset()) {
System.out.println("WatchKey est désactivé");
return;
}
}
}
}
** Résultat d'exécution **
La description
WatchService watcher;
try {
watcher = FileSystems.getDefault().newWatchService();
...
} catch (IOException e) {
e.printStackTrace();
return;
}
WatchService
avec FileSystems.getDefault (). NewWatchService ()
import static java.nio.file.StandardWatchEventKinds.*;
...
Watchable path = Paths.get("./build");
path.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
Path
hérite de Watchable
, il peut donc être utilisé comme cible de surveillance.
--Spécifiez l'événement que vous souhaitez surveiller après le deuxième argument
--Spécifiez les constantes définies dans StandardWatchEventKinds
--Cependant, ʻOVERFLOW` n'a pas besoin d'être spécifié (les détails seront décrits plus tard). while (true) {
WatchKey watchKey;
try {
watchKey = watcher.take();
} catch (InterruptedException e) {
System.err.println(e.getMessage());
return;
}
...
}
--Lorsque vous exécutez la méthode take ()
de WatchService
, il attend le traitement jusqu'à ce que l'événement à surveiller se produise.
--Un objet WatchKey
est renvoyé lorsqu'un événement surveillé se produit
--WatchKey
est un objet qui est créé lorsque vous enregistrez une cible de surveillance avec register () ʻof
Watchable`, et vous pouvez contrôler l'état de la surveillance comme le référencement des informations d'événement qui se sont produites pour chaque cible de surveillance et l'annulation de la surveillance. ça peut
for (WatchEvent<?> event : watchKey.pollEvents()) {
Kind<?> kind = event.kind();
Object context = event.context();
System.out.println("kind=" + kind + ", context=" + context);
}
WatchEvent
) avec pollEvents () ʻof
WatchKey`.WatchEvent
--kind
: Type d'événement survenu
--context
: objet Path
avec un chemin relatif vers l'entrée créée / modifiée / supprimée (fichier ou dossier)
--count
: nombre de fois où ce type d'événement s'est produit if (!watchKey.reset()) {
System.out.println("WatchKey est désactivé");
return;
}
--Enfin, exécutez reset ()
de WatchKey
――Pourquoi vous devez appeler reset ()
sera expliqué plus tard.
reset ()
est boolean
, qui vous indique si WatchKey
est toujours valide.
--Si false
, la WatchKey
est désactivée et la surveillance ne peut pas continuer.WatchKey.cancel ()
WatchService.close ()
a annulé la surveillance de WatchService
--WatchKey
a deux états, "READY" et "SIGNALLED".
--Lorsqu'il est généré par Watchable.register ()
, il est à l'état READY
.
SIGNALLED
lorsqu'un événement est détecté
--Lorsque vous exécutez WatchKey.reset ()
, il revient à l'état READY
.--WatchService
stocke la WatchKey
créée lorsque vous avez exécuté Watchable.register ()
WatchKey
dont le statut est SIGNALLED
.
--La WatchKey
immédiatement après sa création est dans l'état READY
, donc elle n'est pas dans la file d'attente.WatchKey
dont le statut est SIGNALLED
est ajoutée à la file d'attente de WatchService
.WatchService
peuvent récupérer WatchKey
au début de la file d'attente en utilisant les méthodesWatchService.take ()
oupoll ()
(supprimées de la file d'attente). Ru)
--take ()
bloque le traitement lorsque la file d'attente est vide et attend que WatchKey
soit ajouté à la file d'attente
--poll ()
retourne null
sans blocage si la file d'attente est vide
--Pour poll ()
, vous pouvez spécifier le délai d'expiration comme argument et le laisser attendre jusque-là.
--La WatchKey
sortie de la file d'attente avec take () ʻou
poll ()` ne sera pas remise en file d'attente telle quelle.WatchKey
supprimé de la file d'attente est toujours SIGNALLED
WatchKey
--WatchKey
est sécurisé pour les threads, donc même si des informations d'événement sont ajoutées pendant le traitement de l'événement, l'état interne ne sera pas corrompu.
--pollEvents ()
retourne une copie des informations d'événement que WatchKey avait à ce moment-là.pollEvents ()
ont été supprimées de l'intérieur de WatchKey
.
--En bref
--Une fois retiré de la file d'attente, WatchKey
ne sera plus mis en file d'attente s'il n'est pas touché.
--Si vous n'êtes pas dans la file d'attente, vous ne pouvez pas le récupérer avec take ()
ou poll ()
Cela signifie
--L'état doit être retourné à «READY» pour que «WatchKey» soit à nouveau mis en file d'attente.WatchKey
sont vides (pas d'événements non traités), le statut revient à READY
.SIGNALLED
.Résumé,
--La WatchKey
immédiatement après la création est dans l'état READY
.
--Si un événement est détecté et changé en SIGNALLED
, il sera ajouté à la file d'attente dans WatchService
.
WatchKey
de la file d'attente avec take ()
, poll ()
--Une fois qu'une WatchKey
est hors de la file d'attente, elle ne retournera pas dans la file d'attente sans autorisation à moins que vous n'exécutiez reset ()
.
--S'il y a des événements non traités, ils peuvent être mis en file d'attente en tant que SIGNALLED
S'il n'y a aucun événement non traité, il sera à l'état READY
, et la prochaine fois que l'événement surveillé se produira, il sera à nouveau SENGALLED
et sera mis en file d'attente.package sample.watch;
...
public class Main {
public static void main(String[] args) {
...
while (true) {
WatchKey watchKey;
try {
watchKey = watcher.take();
Thread.sleep(1000);★ Ajout
} catch (InterruptedException e) {
...
}
...
}
}
}
** Résultat d'exécution **
La description
--Si un événement est perdu ou détruit pour une raison quelconque, un événement spécial appelé «OVERFLOW» est utilisé.
--Par exemple, selon l'environnement d'exécution, il peut y avoir une limite sur le nombre d'événements stockés dans WatchKey
, et si un événement qui dépasse cette limite se produit, l'événement ʻOVERFLOW sera utilisé. --Dans l'exemple ci-dessus, attendez 1 seconde avant d'obtenir l'événement (
pollEvents ()), enregistrez tous les événements d'un grand nombre de générations de fichiers dans
WatchKey, et générez de force ʻOVERFLOW
. Est
est notifié lorsque la condition est remplie même si elle n'est pas spécifiée comme événement surveillé dans l'enregistrement avec
Watchable.register ()`.package sample.watch;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Paths;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.nio.file.Watchable;
import static java.nio.file.StandardWatchEventKinds.*;
import static java.nio.file.WatchEvent.*;
public class Main {
public static void main(String[] args) {
WatchService watcher;
WatchKey fooKey;
WatchKey barKey;
try {
watcher = FileSystems.getDefault().newWatchService();
Watchable foo = Paths.get("./build/foo");
fooKey = foo.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
Watchable bar = Paths.get("./build/bar");
barKey = bar.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
} catch (IOException e) {
e.printStackTrace();
return;
}
while (true) {
WatchKey watchKey;
try {
watchKey = watcher.take();
} catch (InterruptedException e) {
System.err.println(e.getMessage());
return;
}
for (WatchEvent<?> event : watchKey.pollEvents()) {
Kind<?> kind = event.kind();
if (kind == OVERFLOW) {
continue;
}
Object context = event.context();
String directory;
if (watchKey == fooKey) {
directory = "foo";
} else if (watchKey == barKey) {
directory = "bar";
} else {
directory = "unknown";
}
System.out.println("directory=" + directory + ", kind=" + kind + ", context=" + context);
}
if (!watchKey.reset()) {
System.out.println("WatchKey est désactivé");
return;
}
}
}
}
** Résultat d'exécution **
La description
--Un WatchService
peut surveiller plusieurs dossiers
WatchKey
obtenue parWatchService.take (). --Si vous enregistrez la
WatchKey qui est retournée comme valeur de retour de
Watchable.register ()`, vous pouvez la comparer pour identifier dans quel dossier se trouve l'événement.Recommended Posts