Libraryless. Click here for Pure Java version (7325L/41K).
1 | import java.nio.file.*; |
2 | import static java.nio.file.StandardWatchEventKinds.*; |
3 | |
4 | sclass FileWatchService implements AutoCloseable { |
5 | settable int interval = 50; // larger interval helps show less duplicate events (https://stackoverflow.com/questions/16777869/java-7-watchservice-ignoring-multiple-occurrences-of-the-same-event/34818620#34818620) |
6 | int sleepSeconds = 60; // any drawback to this being very high? not sure |
7 | |
8 | WatchService watchService; |
9 | new MultiMap<WatchKey, IVF1<File>> listeners; |
10 | Thread pollThread; |
11 | volatile bool closed; |
12 | |
13 | *() ctex { |
14 | watchService = FileSystems.getDefault().newWatchService(); |
15 | } |
16 | |
17 | public void close { set closed; dispose watchService; } |
18 | |
19 | WatchKey addListenerImpl(File path, IVF1<File> listener, WatchEvent.Kind... eventKinds) ctex { |
20 | if (path == null) null; |
21 | startPollThread(); |
22 | WatchKey key = path.toPath().register(watchService, eventKinds); |
23 | listeners.put(key, listener); |
24 | ret key; |
25 | } |
26 | |
27 | void addNonRecursiveListener(File path, IVF1<File> listener) { |
28 | addListenerImpl(path, listener, jdk_watchService_allEventKinds()); |
29 | } |
30 | |
31 | void addRecursiveListener(File path, IVF1<File> listener) { |
32 | Set<File> listeningTo = synchroSet(); |
33 | IVF1<File> listener2 = new IVF1<File> { |
34 | public void get(File f) { |
35 | // TODO: remove listeners on deleted directory |
36 | bool isDir = f.isDirectory(); |
37 | if (isDir && listeningTo.add(f)) pcall-short { |
38 | addListenerImpl(f, this, jdk_watchService_allEventKinds()); |
39 | } |
40 | callF(listener, f); |
41 | } |
42 | }; |
43 | addListenerImpl(path, listener2, jdk_watchService_allEventKinds()); |
44 | for (File subDir : findAllDirs(path)) |
45 | addListenerImpl(subDir, listener2, jdk_watchService_allEventKinds()); |
46 | } |
47 | |
48 | synchronized void startPollThread() { |
49 | if (pollThread != null) ret; |
50 | pollThread = startThread("File Watch Service", r { |
51 | try { |
52 | while (licensed() && !closed) { |
53 | WatchKey key = watchService.poll(sleepSeconds, TimeUnit.SECONDS); |
54 | if (key != null) { |
55 | Path dir = cast key.watchable(); |
56 | sleep(interval); |
57 | L<WatchEvent<?>> events = key.pollEvents(); |
58 | new LinkedHashSet<File> changedFiles; |
59 | for (WatchEvent<?> event : reversedIterator(events)) pcall { |
60 | final Path changed = (Path) event.context(); |
61 | if (changed == null) continue; |
62 | File full = newFile(dir.toFile(), changed.toFile().getPath()); |
63 | changedFiles.add(full); |
64 | //print("WatchService Changed: " + full + ", " + event.kind()); |
65 | } |
66 | for (File f : changedFiles) |
67 | pcallFAll(listeners.get(key), f); |
68 | key.reset(); |
69 | } |
70 | } |
71 | } catch (ClosedWatchServiceException e) {} |
72 | }); |
73 | } |
74 | } |
Began life as a copy of #1019344
download show line numbers debug dex old transpilations
Travelled to 4 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx, vouqrxazstgt
No comments. add comment
Snippet ID: | #1030467 |
Snippet name: | FileWatchService [OK] |
Eternal ID of this version: | #1030467/20 |
Text MD5: | 0cc561d084308f6582edc449719f5e27 |
Transpilation MD5: | 949ab65b572101e5d018a93f2dcb8ea4 |
Author: | stefan |
Category: | javax / io |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2022-02-01 18:53:13 |
Source code size: | 2873 bytes / 74 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 231 / 522 |
Version history: | 19 change(s) |
Referenced in: | [show references] |