Skip to content

Instantly share code, notes, and snippets.

@MartinSadovy
Last active October 23, 2017 15:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MartinSadovy/4665da82f2ab10bd8184add08bf7ed09 to your computer and use it in GitHub Desktop.
Save MartinSadovy/4665da82f2ab10bd8184add08bf7ed09 to your computer and use it in GitHub Desktop.
Using Java WatchService in recursive. Classic WatchService provides only file name without path, this provides absolute path
package cz.sodae.utils
import java.nio.file.*
import java.nio.file.attribute.BasicFileAttributes
import java.util.concurrent.ConcurrentHashMap
interface RecursiveWatchServiceListener {
fun onCreate(path: Path)
fun onModify(path: Path)
fun onDelete(path: Path)
}
class RecursiveWatchService(private val listener: RecursiveWatchServiceListener) {
private val dirs: ConcurrentHashMap<String, WatchService> = ConcurrentHashMap()
private var running = false
fun stop() {
running = false
}
fun recursiveRegister(path: Path) {
Files.walkFileTree(path, object : SimpleFileVisitor<Path>() {
override fun preVisitDirectory(dir: Path, attrs: BasicFileAttributes): FileVisitResult {
val watchService = dir.fileSystem.newWatchService()
dirs[dir.toAbsolutePath().toString()] = watchService
dir.register(
watchService,
StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_DELETE,
StandardWatchEventKinds.ENTRY_MODIFY
)
return FileVisitResult.CONTINUE
}
})
}
fun run() {
running = true
Thread({
while (running) {
dirs.forEach { dir, watchService ->
val key = watchService.poll() ?: return@forEach
for (watchEvent in key.pollEvents()) {
val kind = watchEvent.kind()
if (StandardWatchEventKinds.OVERFLOW === kind) {
continue // loop
}
val name = (watchEvent as WatchEvent<Path>).context()
val fullPath = Paths.get(dir, name.fileName.toString())
try {
when {
StandardWatchEventKinds.ENTRY_CREATE === kind -> {
if (fullPath.toFile().isDirectory) {
recursiveRegister(fullPath)
}
listener.onCreate(fullPath)
}
StandardWatchEventKinds.ENTRY_MODIFY === kind -> listener.onModify(fullPath)
StandardWatchEventKinds.ENTRY_DELETE === kind -> listener.onDelete(fullPath)
}
} catch (e: Throwable) {
e.printStackTrace()
}
}
if (!key.reset()) {
dirs.remove(dir)
}
}
}
}).start()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment