Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

74
LINES

< > BotCompany Repo | #1030467 // FileWatchService [OK]

JavaX fragment (include) [tags: use-pretranspiled]

Libraryless. Click here for Pure Java version (7325L/41K).

import java.nio.file.*;
import static java.nio.file.StandardWatchEventKinds.*;

sclass FileWatchService implements AutoCloseable {
  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)
  int sleepSeconds = 60; // any drawback to this being very high? not sure
  
  WatchService watchService;
  new MultiMap<WatchKey, IVF1<File>> listeners;
  Thread pollThread;
  volatile bool closed;
  
  *() ctex {
    watchService = FileSystems.getDefault().newWatchService();
  }
  
  public void close { set closed; dispose watchService; }
  
  WatchKey addListenerImpl(File path, IVF1<File> listener, WatchEvent.Kind... eventKinds) ctex {
    if (path == null) null;
    startPollThread();
    WatchKey key = path.toPath().register(watchService, eventKinds);
    listeners.put(key, listener);
    ret key;
  }
  
  void addNonRecursiveListener(File path, IVF1<File> listener) {
    addListenerImpl(path, listener, jdk_watchService_allEventKinds());
  }
  
  void addRecursiveListener(File path, IVF1<File> listener) {
    Set<File> listeningTo = synchroSet();
    IVF1<File> listener2 = new IVF1<File> {
      public void get(File f) {
        // TODO: remove listeners on deleted directory
        bool isDir = f.isDirectory();
        if (isDir && listeningTo.add(f)) pcall-short {
          addListenerImpl(f, this, jdk_watchService_allEventKinds());
        }
        callF(listener, f);
      }
    };
    addListenerImpl(path, listener2, jdk_watchService_allEventKinds());
    for (File subDir : findAllDirs(path))
      addListenerImpl(subDir, listener2, jdk_watchService_allEventKinds());
  }

  synchronized void startPollThread() {
    if (pollThread != null) ret;
    pollThread = startThread("File Watch Service", r {
      try {
        while (licensed() && !closed) { 
          WatchKey key = watchService.poll(sleepSeconds, TimeUnit.SECONDS);
          if (key != null) {
            Path dir = cast key.watchable();
            sleep(interval);
            L<WatchEvent<?>> events = key.pollEvents();
            new LinkedHashSet<File> changedFiles;
            for (WatchEvent<?> event : reversedIterator(events)) pcall {
              final Path changed = (Path) event.context();
              if (changed == null) continue;
              File full = newFile(dir.toFile(), changed.toFile().getPath());
              changedFiles.add(full);
              //print("WatchService Changed: " + full + ", " + event.kind());
            }
            for (File f : changedFiles)
              pcallFAll(listeners.get(key), f);
            key.reset();
          }
        }
      } catch (ClosedWatchServiceException e) {}
    });
  }
}

Author comment

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: 325 / 632
Version history: 19 change(s)
Referenced in: #1034167 - Standard Classes + Interfaces (LIVE, continuation of #1003674)