Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/sample/nio/file/WatchDir.java
38829 views
/*1* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.2*3* Redistribution and use in source and binary forms, with or without4* modification, are permitted provided that the following conditions5* are met:6*7* - Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9*10* - Redistributions in binary form must reproduce the above copyright11* notice, this list of conditions and the following disclaimer in the12* documentation and/or other materials provided with the distribution.13*14* - Neither the name of Oracle nor the names of its15* contributors may be used to endorse or promote products derived16* from this software without specific prior written permission.17*18* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS19* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,20* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR21* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR22* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,23* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,24* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR25* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF26* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING27* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS28* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.29*/3031/*32* This source code is provided to illustrate the usage of a given feature33* or technique and has been deliberately simplified. Additional steps34* required for a production-quality application, such as security checks,35* input validation and proper error handling, might not be present in36* this sample code.37*/383940import java.nio.file.*;41import static java.nio.file.StandardWatchEventKinds.*;42import static java.nio.file.LinkOption.*;43import java.nio.file.attribute.*;44import java.io.IOException;4546/**47* Example to watch a directory (or tree) for changes to files.48*/4950public class WatchDir {5152private final WatchService watcher;53private final boolean recursive;54private boolean trace = false;55private int count;5657@SuppressWarnings("unchecked")58static <T> WatchEvent<T> cast(WatchEvent<?> event) {59return (WatchEvent<T>)event;60}6162/**63* Register the given directory with the WatchService64*/65private void register(Path dir) throws IOException {66WatchKey key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);67count++;68if (trace)69System.out.format("register: %s\n", dir);70}7172/**73* Register the given directory, and all its sub-directories, with the74* WatchService.75*/76private void registerAll(final Path start) throws IOException {77// register directory and sub-directories78Files.walkFileTree(start, new SimpleFileVisitor<Path>() {79@Override80public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)81throws IOException82{83register(dir);84return FileVisitResult.CONTINUE;85}86});87}8889/**90* Creates a WatchService and registers the given directory91*/92WatchDir(Path dir, boolean recursive) throws IOException {93this.watcher = FileSystems.getDefault().newWatchService();94this.recursive = recursive;9596if (recursive) {97System.out.format("Scanning %s ...\n", dir);98registerAll(dir);99System.out.println("Done.");100} else {101register(dir);102}103104// enable trace after initial registration105this.trace = true;106}107108/**109* Process all events for keys queued to the watcher110*/111void processEvents() {112for (;;) {113114// wait for key to be signalled115WatchKey key;116try {117key = watcher.take();118} catch (InterruptedException x) {119return;120}121122for (WatchEvent<?> event: key.pollEvents()) {123WatchEvent.Kind kind = event.kind();124125// TBD - provide example of how OVERFLOW event is handled126if (kind == OVERFLOW) {127continue;128}129130// Context for directory entry event is the file name of entry131WatchEvent<Path> ev = cast(event);132Path name = ev.context();133Path child = ((Path)key.watchable()).resolve(name);134135// print out event136System.out.format("%s: %s\n", event.kind().name(), child);137138// if directory is created, and watching recursively, then139// register it and its sub-directories140if (recursive && (kind == ENTRY_CREATE)) {141try {142if (Files.isDirectory(child, NOFOLLOW_LINKS)) {143registerAll(child);144}145} catch (IOException x) {146// ignore to keep sample readbale147}148}149}150151// reset key152boolean valid = key.reset();153if (!valid) {154// directory no longer accessible155count--;156if (count == 0)157break;158}159}160}161162static void usage() {163System.err.println("usage: java WatchDir [-r] dir");164System.exit(-1);165}166167public static void main(String[] args) throws IOException {168// parse arguments169if (args.length == 0 || args.length > 2)170usage();171boolean recursive = false;172int dirArg = 0;173if (args[0].equals("-r")) {174if (args.length < 2)175usage();176recursive = true;177dirArg++;178}179180// register directory and process its events181Path dir = Paths.get(args[dirArg]);182new WatchDir(dir, recursive).processEvents();183}184}185186187