Java WatchService не генерирует события во время просмотра подключенных дисков - PullRequest
24 голосов
/ 12 декабря 2011

Я реализовал средство просмотра файлов, но заметил, что средство просмотра файлов java nio не генерирует события для файлов, копируемых на подключенные диски.Например, я запустил средство просмотра файлов в Unix для просмотра локального каталога (/sharedfolder), который отображается в windows (H:\), а затем я поместил файл в этот каталог (H:\), носредство просмотра файлов не сгенерировало никаких событий.Теперь, если я запускаю средство просмотра файлов в Windows для наблюдения за подключенным диском (H:\), который ссылается на путь Unix (/sharedfolder), а из Unix я помещаю файл в эту папку, средство просмотра файлов идентифицирует изменение и генерируетсобытие.Похоже, ошибка, или, может быть, я что-то упускаю, какие-то мысли?

Ответы [ 5 ]

25 голосов
/ 19 сентября 2012

У меня та же проблема, когда я пытаюсь посмотреть, как подключен общий доступ к Windows через CIFS.Кажется невозможным получить событий файловой системы для монтирования CIFS .

В реализации linux Java 7 NIO FileWatcher используется inotify .Inotify - это подсистема ядра Linux, которая замечает изменения в файловой системе, которая идеально подходит для локальных каталогов, но, очевидно, не для CIFS монтирует .

В Oracle, похоже, не является высоким приоритетом исправления эта ошибка .(Это их ответственность? Больше проблем с ОС ...)

JNotify также использует inotify в системах Linux, так что это тоже не вариант.

Таким образом, мониторинг подключенных дисков, к сожалению, ограничен поллерами:

  • Apache VFS DefaultFileMonitor для опроса каталогов (смонтированный общий ресурс)
  • на основе файлового опросана стандартном Java API.
  • Пользовательский файл Poller с jCIFS (поэтому общий ресурс не нужно монтировать на хосте)

Я будувероятно, попробуйте Apache VFS Monitor, поскольку он обнаруживает создание, обновление и удаление файлов из коробки.Требуется смонтировать общий ресурс, но это дает ОС ответственность за соединения CIFS, а не мое приложение.

4 голосов
/ 12 декабря 2011

Функциональность просмотра файлов в JDK зависит от платформы, поскольку она использует собственные библиотеки, поэтому на разных платформах она может работать по-разному. Я удивлен, что это работает для сетевых дисков вообще - Windows должна опрашивать сетевые диски на предмет изменений, в то время как Linux этого не делает (по правде говоря, я должен сказать).

Обычно этот вид мониторинга реализован в ядре ОС, которое, очевидно, знает, какие файлы модифицируются / создаются / и т.д. локально, но у ОС нет простых способов узнать, что происходит на сетевом диске, поскольку она не имеет исключительного контроля над это.

2 голосов
/ 01 мая 2015

У меня была такая же проблема. Я решил эту проблему, создав новый поток в классе de main и периодически касаясь файлов, чтобы сработало новое событие изменения.

Образец опрашивает каталог каждые 10 секунд и делает касание.

package com.ardevco.files;

import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.FileTime;
import java.util.ArrayList;
import java.util.List;

public class Touch implements Runnable {

    private Path touchPath;

    public Touch(Path touchPath) {
        this.touchPath = touchPath;
        this.checkPath = checkPath;

    }

    public static void touch(Path file) throws IOException {
        long timestamp = System.currentTimeMillis();
        touch(file, timestamp);
    }

    public static void touch(Path file, long timestamp) throws IOException {
        if (Files.exists(file)) {
            FileTime ft = FileTime.fromMillis(timestamp);
            Files.setLastModifiedTime(file, ft);
        }
    }

    List<Path> listFiles(Path path) throws IOException {
        final List<Path> files = new ArrayList<>();
        try (DirectoryStream<Path> stream = Files.newDirectoryStream(path)) {
            for (Path entry : stream) {
                if (Files.isDirectory(entry)) {
                    files.addAll(listFiles(entry));
                }
                files.add(entry);
            }
        }
        return files;
    }

    @Override
    public void run() {
        while (true) {
            try {
                for (Path path : listFiles(touchPath)) {
                    touch(path);
                }
            } catch (IOException e) {
                System.out.println("Exception: " + e);
            }

            try {
                Thread.sleep(10000L);
            } catch (InterruptedException e) {
                System.out.println("Exception: " + e);
            }
        }

    }

}
1 голос
/ 05 мая 2013

Я тоже столкнулся с этим и пришел к тому же выводу, что и все остальные здесь (CIFS + inotify = no go).

Однако, поскольку мой рабочий процесс зависел как от удаленных монтировок, так и от инструментов автокомпиляции, которыеполагаясь на inotify, я в итоге создал (довольно отчаянное и хакерское) решение, которое в основном просто использует опрос для отслеживания изменений, а затем снова касается тех же файлов на смонтированной стороне, что, как кажется, вызывает , вызывает inotifyСобытия.Это не мой гордый момент.

Сказав это, он работает, так что наслаждайтесь: http://github.com/rubyruy/watchntouch

1 голос
/ 19 сентября 2012

У меня были похожие проблемы со скриптом Python, который просматривал содержимое файла журнала в удаленном каталоге Windows.

Вот мой ответ.

При отображении удаленного диска из Unix, в /etc/fstab используйте //xxx.xxx.xxx.xxx/shareddrive /media/shareddrive cifs username=xxxx,password=xxxx,**directio** 0 0

Вы можете использовать файл учетных данных, чтобы избежать ввода пароля в виде простого текста.

Команда может меняться в зависимости от версии Unix, это было протестировано в Debian. Это должно работать как задумано. Можете ли вы сказать мне, если это работает? Я планирую реализовать то же самое в Java, поэтому ответ может быть полезен и для меня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...