Search in sources :

Example 16 with WatchEvent

use of java.nio.file.WatchEvent in project rxjava-file by davidmoten.

the class OperatorFileTailer method reportNewLines.

private static Func1<Object, Observable<byte[]>> reportNewLines(final File file, final AtomicLong currentPosition, final int maxBytesPerEmission) {
    return new Func1<Object, Observable<byte[]>>() {

        @Override
        public Observable<byte[]> call(Object event) {
            // reset current position if file is moved or deleted
            if (event instanceof WatchEvent) {
                WatchEvent<?> w = (WatchEvent<?>) event;
                String kind = w.kind().name();
                if (kind.equals(StandardWatchEventKinds.ENTRY_CREATE.name())) {
                    currentPosition.set(0);
                }
            }
            long length = file.length();
            if (length > currentPosition.get()) {
                try {
                    final FileInputStream fis = new FileInputStream(file);
                    fis.skip(currentPosition.get());
                    // termination or unsubscription
                    return Observable.using(new Func0<InputStream>() {

                        @Override
                        public InputStream call() {
                            return fis;
                        }
                    }, new Func1<InputStream, Observable<byte[]>>() {

                        @Override
                        public Observable<byte[]> call(InputStream t1) {
                            return Bytes.from(fis, maxBytesPerEmission).doOnNext(new Action1<byte[]>() {

                                @Override
                                public void call(byte[] bytes) {
                                    currentPosition.addAndGet(bytes.length);
                                }
                            });
                        }
                    }, new Action1<InputStream>() {

                        @Override
                        public void call(InputStream is) {
                            try {
                                is.close();
                            } catch (IOException e) {
                            // don't care
                            }
                        }
                    });
                } catch (IOException e) {
                    return Observable.error(e);
                }
            } else
                return Observable.empty();
        }
    };
}
Also used : Action1(rx.functions.Action1) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) IOException(java.io.IOException) FileInputStream(java.io.FileInputStream) Observable(rx.Observable) WatchEvent(java.nio.file.WatchEvent) Func1(rx.functions.Func1)

Example 17 with WatchEvent

use of java.nio.file.WatchEvent in project rxjava-file by davidmoten.

the class FileObservableTest method testCreateAndModifyEventsForANonDirectoryFileBlockForever.

@Test
public void testCreateAndModifyEventsForANonDirectoryFileBlockForever() throws InterruptedException, IOException {
    File file = new File("target/f");
    Observable<WatchEvent<?>> events = FileObservable.from(file).kind(ENTRY_MODIFY).kind(ENTRY_CREATE).events();
    checkCreateAndModifyEvents(file, events);
}
Also used : WatchEvent(java.nio.file.WatchEvent) File(java.io.File) Test(org.junit.Test)

Example 18 with WatchEvent

use of java.nio.file.WatchEvent in project rxjava-file by davidmoten.

the class FileObservableTest method checkCreateAndModifyEvents.

private void checkCreateAndModifyEvents(File file, Observable<WatchEvent<?>> events) throws InterruptedException, IOException, FileNotFoundException {
    file.delete();
    final CountDownLatch latch = new CountDownLatch(1);
    @SuppressWarnings("unchecked") final List<Kind<?>> eventKinds = Mockito.mock(List.class);
    InOrder inOrder = Mockito.inOrder(eventKinds);
    final AtomicInteger errorCount = new AtomicInteger(0);
    Subscription sub = events.subscribeOn(Schedulers.io()).subscribe(new Observer<WatchEvent<?>>() {

        @Override
        public void onCompleted() {
            System.out.println("completed");
        }

        @Override
        public void onError(Throwable e) {
            errorCount.incrementAndGet();
        }

        @Override
        public void onNext(WatchEvent<?> event) {
            System.out.println("event=" + event);
            eventKinds.add(event.kind());
            latch.countDown();
        }
    });
    // sleep long enough for WatchService to start
    Thread.sleep(1000);
    file.createNewFile();
    FileOutputStream fos = new FileOutputStream(file, true);
    fos.write("hello there".getBytes());
    fos.close();
    // give the WatchService time to register the change
    Thread.sleep(100);
    assertTrue(latch.await(30000, TimeUnit.MILLISECONDS));
    inOrder.verify(eventKinds).add(StandardWatchEventKinds.ENTRY_CREATE);
    inOrder.verify(eventKinds).add(StandardWatchEventKinds.ENTRY_MODIFY);
    inOrder.verifyNoMoreInteractions();
    sub.unsubscribe();
    Thread.sleep(100);
    assertEquals(0, errorCount.get());
}
Also used : InOrder(org.mockito.InOrder) CountDownLatch(java.util.concurrent.CountDownLatch) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Kind(java.nio.file.WatchEvent.Kind) FileOutputStream(java.io.FileOutputStream) WatchEvent(java.nio.file.WatchEvent) Subscription(rx.Subscription)

Example 19 with WatchEvent

use of java.nio.file.WatchEvent in project fakereplace by fakereplace.

the class WatchServiceFileSystemWatcher method run.

@Override
public void run() {
    while (!stopped) {
        try {
            final WatchKey key = watchService.take();
            if (key != null) {
                try {
                    PathData pathData = pathDataByKey.get(key);
                    if (pathData != null) {
                        List<WatchEvent<?>> events = new ArrayList<>(key.pollEvents());
                        final List<FileChangeEvent> results = new ArrayList<>();
                        List<WatchEvent<?>> latest;
                        do {
                            // we need to wait till nothing has changed in 500ms to make sure we have picked up all the changes
                            Thread.sleep(WAIT_TIME);
                            latest = key.pollEvents();
                            events.addAll(latest);
                        } while (!latest.isEmpty());
                        final Set<Path> addedFiles = new HashSet<>();
                        final Set<Path> deletedFiles = new HashSet<>();
                        for (WatchEvent<?> event : events) {
                            Path eventPath = (Path) event.context();
                            Path targetFile = ((Path) key.watchable()).resolve(eventPath);
                            FileChangeEvent.Type type;
                            if (event.kind() == ENTRY_CREATE) {
                                type = FileChangeEvent.Type.ADDED;
                                addedFiles.add(targetFile);
                                if (Files.isDirectory(targetFile)) {
                                    try {
                                        addWatchedDirectory(pathData, targetFile);
                                    } catch (IOException e) {
                                        e.printStackTrace();
                                    }
                                }
                            } else if (event.kind() == ENTRY_MODIFY) {
                                type = FileChangeEvent.Type.MODIFIED;
                            } else if (event.kind() == ENTRY_DELETE) {
                                type = FileChangeEvent.Type.REMOVED;
                                deletedFiles.add(targetFile);
                            } else {
                                continue;
                            }
                            results.add(new FileChangeEvent(targetFile, type));
                        }
                        key.pollEvents().clear();
                        // now we need to prune the results, to remove duplicates
                        // e.g. if the file is modified after creation we only want to
                        // show the create event
                        final List<FileChangeEvent> newEvents = new ArrayList<>();
                        Iterator<FileChangeEvent> it = results.iterator();
                        while (it.hasNext()) {
                            FileChangeEvent event = it.next();
                            boolean added = addedFiles.contains(event.getFile());
                            boolean deleted = deletedFiles.contains(event.getFile());
                            if (event.getType() == FileChangeEvent.Type.MODIFIED) {
                                if (added || deleted) {
                                    it.remove();
                                }
                            } else if (event.getType() == FileChangeEvent.Type.ADDED) {
                                if (deleted) {
                                    it.remove();
                                    // if it was both deleted and added it was modified
                                    newEvents.add(new FileChangeEvent(event.getFile(), FileChangeEvent.Type.MODIFIED));
                                }
                            } else if (event.getType() == FileChangeEvent.Type.REMOVED) {
                                if (added) {
                                    it.remove();
                                }
                            }
                        }
                        results.addAll(newEvents);
                        if (!results.isEmpty()) {
                            for (FileChangeCallback callback : pathData.callbacks) {
                                invokeCallback(callback, results);
                            }
                        }
                    }
                } finally {
                    // if the key is no longer valid remove it from the files list
                    if (!key.reset()) {
                        files.remove(key.watchable());
                    }
                }
            }
        } catch (InterruptedException e) {
        // ignore
        } catch (ClosedWatchServiceException cwse) {
            // @see https://developer.jboss.org/message/911519
            break;
        }
    }
}
Also used : Path(java.nio.file.Path) WatchKey(java.nio.file.WatchKey) ArrayList(java.util.ArrayList) IOException(java.io.IOException) ClosedWatchServiceException(java.nio.file.ClosedWatchServiceException) WatchEvent(java.nio.file.WatchEvent) HashSet(java.util.HashSet)

Example 20 with WatchEvent

use of java.nio.file.WatchEvent in project sirix by sirixdb.

the class FileSystemWatcher method watch.

/**
 * Watch the directory for changes.
 *
 * @param visitor optional visitor
 * @param index an index of the directory paths to watch
 * @throws IOException if an I/O error occurs
 * @throws NullPointerException if {@code pIndex} is {@code null}
 */
public void watch(final Visitor<XdmNodeWriteTrx> visitor, final Map<Path, FileSystemPath> index) throws IOException {
    final WatchService watcher = FileSystems.getDefault().newWatchService();
    final WatchRecursivelyVisitor fileVisitor = WatchRecursivelyVisitor.getInstance(watcher);
    Files.walkFileTree(mPath, fileVisitor);
    checkNotNull(index);
    for (; mState == State.LOOP; ) {
        // Wait for key to be signaled.
        WatchKey key;
        try {
            key = watcher.take();
        } catch (InterruptedException x) {
            return;
        }
        final Map<WatchKey, Path> keys = fileVisitor.getKeys();
        final Path dir = keys.get(key);
        if (dir == null) {
            LOGWRAPPER.error("WatchKey not recognized!!");
            continue;
        }
        for (WatchEvent<?> event : key.pollEvents()) {
            final WatchEvent.Kind<?> kind = event.kind();
            /*
         * This key is registered only for ENTRY_CREATE events, but an OVERFLOW event can occur
         * regardless if events are lost or discarded.
         */
            if (kind == OVERFLOW) {
                continue;
            }
            /*
         * The filename is the context of the event. Cast is safe because we registered a path
         * instance.
         */
            WatchEvent<?> ev = event;
            for (int i = 0; i < ev.count(); i++) {
                final Path name = (Path) ev.context();
                final Path child = dir.resolve(name);
                if (kind == ENTRY_CREATE && Files.isDirectory(child, NOFOLLOW_LINKS)) {
                    Files.walkFileTree(child, new SimpleFileVisitor<Path>() {

                        @Override
                        public FileVisitResult preVisitDirectory(final Path dir, final BasicFileAttributes attrs) throws IOException {
                            checkNotNull(dir);
                            checkNotNull(attrs);
                            final WatchKey key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
                            keys.put(key, dir);
                            entryCreated(visitor, index, dir);
                            return FileVisitResult.CONTINUE;
                        }

                        @Override
                        public FileVisitResult visitFile(final Path pFile, final BasicFileAttributes pAttrs) throws IOException {
                            checkNotNull(pFile);
                            checkNotNull(pAttrs);
                            entryCreated(visitor, index, pFile);
                            return FileVisitResult.CONTINUE;
                        }
                    });
                } else {
                    processEvent(ev, visitor, index, watcher, child);
                }
            }
        }
        /*
       * Reset the key -- this step is critical if you want to receive further watch events. If the
       * key is no longer valid, the directory is inaccessible so exit the loop.
       */
        final boolean valid = key.reset();
        if (!valid) {
            keys.remove(key);
            // All directories are inaccessible.
            if (keys.isEmpty()) {
                mState = State.NOLOOP;
            }
        }
    }
    watcher.close();
}
Also used : Path(java.nio.file.Path) WatchKey(java.nio.file.WatchKey) FileVisitResult(java.nio.file.FileVisitResult) IOException(java.io.IOException) WatchEvent(java.nio.file.WatchEvent) WatchService(java.nio.file.WatchService) BasicFileAttributes(java.nio.file.attribute.BasicFileAttributes)

Aggregations

WatchEvent (java.nio.file.WatchEvent)91 Path (java.nio.file.Path)68 WatchKey (java.nio.file.WatchKey)57 IOException (java.io.IOException)33 File (java.io.File)26 Test (org.junit.Test)24 WatchService (java.nio.file.WatchService)20 BuckEventBus (com.facebook.buck.event.BuckEventBus)13 FakeClock (com.facebook.buck.timing.FakeClock)13 EventBus (com.google.common.eventbus.EventBus)12 ClosedWatchServiceException (java.nio.file.ClosedWatchServiceException)10 EasyMock.anyObject (org.easymock.EasyMock.anyObject)10 ArrayList (java.util.ArrayList)9 HashMap (java.util.HashMap)6 Subscribe (com.google.common.eventbus.Subscribe)5 FakeWatchmanClient (com.facebook.buck.io.FakeWatchmanClient)4 FileSystems (java.nio.file.FileSystems)4 StandardWatchEventKinds (java.nio.file.StandardWatchEventKinds)4 HashSet (java.util.HashSet)4 List (java.util.List)4