I am using FileWatcher to watch a whole hard disk partition in my case its D drive eg: D:/ the code is working fine with one path i provided, all i want is to watch other hard disk partitions as well like C:,D: and E: how can i achieve that here is the code
public class FileWatcher {
private final WatchService watcher;
private final Map<WatchKey, Path> keys;
static Logger log = LoggerFactory.getLogger(GitCloneRepo.class);
/**
* Creates a WatchService and registers the given directory
*/
FileWatcher(Path dir) throws IOException {
this.watcher = FileSystems.getDefault().newWatchService();
this.keys = new HashMap<WatchKey, Path>();
walkAndRegisterDirectories(dir);
}
/**
* Register the given directory with the WatchService; This function will be called by FileVisitor
*/
private void registerDirectory(Path dir) throws IOException
{
WatchKey key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
keys.put(key, dir);
}
/**
* Register the given directory, and all its sub-directories, with the WatchService.
*/
private void walkAndRegisterDirectories(final Path start) throws IOException {
// register directory and sub-directories
Files.walkFileTree(start, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
registerDirectory(dir);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
if (exc instanceof AccessDeniedException) {
return FileVisitResult.SKIP_SUBTREE;
}
return super.visitFileFailed(file, exc);
}
});
}
/**
* Process all events for keys queued to the watcher
*/
void processEvents() {
for (;;) {
// wait for key to be signalled
WatchKey key;
try {
key = watcher.take();
} catch (InterruptedException x) {
log.error("InterruptedException ",x);
return;
}
Path dir = keys.get(key);
if (dir == null) {
log.warn("WatchKey not recognized!!");
continue;
}
for (WatchEvent<?> event : key.pollEvents()) {
@SuppressWarnings("rawtypes")
WatchEvent.Kind kind = event.kind();
// Context for directory entry event is the file name of entry
@SuppressWarnings("unchecked")
Path name = ((WatchEvent<Path>)event).context();
Path child = dir.resolve(name);
log.info("watching files");
// print out event
if (kind == ENTRY_MODIFY) {
log.info("event.kind().name() {}: child {}", event.kind().name(), child);
log.info("child {} ends with docx? {} ",child,child.endsWith(".docx"));
String c= child.toString();
log.info("**child {}***c.endsWith(.docx)"
+ ""
+ " {}",c,c.endsWith(".docx"));
}
// if directory is created, and watching recursively, then register it and its sub-directories
if (kind == ENTRY_CREATE) {
try {
if (Files.isDirectory(child)) {
walkAndRegisterDirectories(child);
}
} catch (IOException x) {
// do something useful
}
}
}
// reset key and remove from set if directory no longer accessible
boolean valid = key.reset();
if (!valid) {
keys.remove(key);
// all directories are inaccessible
if (keys.isEmpty()) {
break;
}
}
}
}
//working code
public static void main(String[] args) throws IOException {
try{
Path dir = Paths.get("D:");
FileWatcher fileWatcher=new FileWatcher(dir);
fileWatcher.processEvents();
}
catch (AccessDeniedException xx) {
log.error("AccessDeniedException ",xx);
}
catch (FileSystemException x) {
log.error("exception",x);
}
}
}
i looked at this question but i did not seemed to solve my problem How to implement file watcher to Watch multiple directories
Your processEvents
method enters an infinite loop and doesn't return until either the thread is interrupted or the path is gone, which means any code after processEvents
won't execute until it's done. If you want your main
method to spin up multiple watchers, you'll need to call processEvents
from other threads, e.g. with Java 8:
// Create watchers
List<FileWatcher> watchers = new ArrayList<>();
try{
watchers.add(new FileWatcher(Paths.get("D:")));
watchers.add(new FileWatcher(Paths.get("E:")));
} catch (AccessDeniedException xx) {
log.error("AccessDeniedException ",xx);
} catch (FileSystemException x) {
log.error("exception",x);
}
// Create and start threads
List<Thread> threads = watchers.stream()
.map(w -> new Thread(w::processEvents))
.peek(Thread::start)
.collect(Collectors.toList());
With Java 7:
// Create watchers
List<FileWatcher> watchers = new ArrayList<>();
try{
watchers.add(new FileWatcher(Paths.get("D:")));
watchers.add(new FileWatcher(Paths.get("E:")));
} catch (AccessDeniedException xx) {
log.error("AccessDeniedException ",xx);
} catch (FileSystemException x) {
log.error("exception",x);
}
// Create and start threads
List<Thread> threads = new ArrayList<>();
for (FileWatcher watcher : watchers) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
watcher.processEvents();
}
});
thread.start();
threads.add(thread);
}