如何在java中监视文件夹的更改?
我有以下代码用于监视文件夹中的java更改:如何在java中监视文件夹的更改?,java,multithreading,file,file-io,Java,Multithreading,File,File Io,我有以下代码用于监视文件夹中的java更改: public class FolderWatcher { // public List<Event> events = new ArrayList<Event>(); public static Event call() throws IOException, InterruptedException { LOG.info("Watching folder");
public class FolderWatcher
{
// public List<Event> events = new ArrayList<Event>();
public static Event call() throws IOException, InterruptedException
{
LOG.info("Watching folder");
Path _directotyToWatch = Paths.get("data/input-files"); // this will be put in the configuration file
WatchService watcherSvc = FileSystems.getDefault().newWatchService();
WatchKey watchKey = _directotyToWatch.register(watcherSvc, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
watchKey = watcherSvc.take();
for (WatchEvent<?> event : watchKey.pollEvents())
{
WatchEvent<Path> watchEvent = castEvent(event);
LOG.info(event.kind().name().toString() + " " + _directotyToWatch.resolve(watchEvent.context()));
String eventName = event.kind().name();
String fileName = _directotyToWatch.resolve(watchEvent.context()).toString();
watchKey.reset();
return new Event(eventName, fileName);
}
return null;
}
@SuppressWarnings("unchecked")
static <T> WatchEvent<T> castEvent(WatchEvent<?> event)
{
return (WatchEvent<T>) event;
}
}
以及:
只要文件的修改(在我的例子中主要是添加)是一个接一个地完成的,并且每次添加都有一点延迟,整个过程就可以完美地工作。但是,如果我同时拖放或添加多个文件。此代码仅检测第一个文件的事件,而不检测其余文件的事件。我甚至把执行时间设为纳秒,但这没用。我想知道这整段代码是否是一种有效的方法。有人能帮我吗。谢谢。为什么不在每个文件夹中存储一个
元数据文件(递归地),在该元数据文件中,可以存储每个文件的文件列表
和修改日期
和大小
。您的线程应该将每个文件夹中的元数据
文件与同一文件夹中的当前文件
进行比较。
这就是如何检测该文件夹中的任何更改
请记住,您应该为其中的每个子文件夹递归执行此操作。每次扫描都应更新元数据
文件。
希望这有帮助。在我的情况下,此代码成功:
try {
Path rootFolder = Paths.get(ctxProperties.getProperty("rootFolder"));
WatchService watcher = rootFolder.getFileSystem().newWatchService();
rootFolder.register(watcher, StandardWatchEventKinds.ENTRY_CREATE);
while (true) {
WatchKey watchKey = watcher.take();
if (watchKey != null) {
for (WatchEvent event : watchKey.pollEvents()) {
if (StandardWatchEventKinds.ENTRY_CREATE.equals(event.kind())) {
String fileName = rootFolder.toString() + "/" + event.context().toString();
String messageStr = convertFileToString(fileName);
if (messageStr != null) {
try {
sendMessage(jmsPublisher, messageStr, getJmsProperties());
moveMessageToProcessedDirectory(fileName, ctxProperties.getProperty("successFolder"), ".ok");
LOGGER.info("JMS message successfully sent");
sleep(Long.parseLong(ctxProperties.getProperty("sleepBetweenMsgMse")));
} catch (Exception e) {
moveMessageToProcessedDirectory(fileName, ctxProperties.getProperty("errorFolder"), ".nok");
}
} else {
LOGGER.error("ERROR: error parsing file content to string with file: " + fileName);
moveMessageToProcessedDirectory(fileName, ctxProperties.getProperty("errorFolder"), ".nok");
}
}
}
boolean valid = watchKey.reset();
if (!valid) {
LOGGER.error("ERROR: the watcher is no longer valid, the directory is inaccessible");
break;
}
} else {
LOGGER.error("ERROR: the watcher is null or not watchable");
break;
}
}
} catch (InterruptedException interruptedException) {
LOGGER.error("InterruptedException: thread got interrupted",interruptedException);
} catch (Exception exception) {
LOGGER.error("Exception: " + exception.getMessage(), exception);
}
您可以看看JavaSE7:Similar-Thread@AlexandreDupriez提供的JavaNIO.2,这应该是一个答案,我想(即使我确信最近在Java中看到了一个类似的问题),这足够重复了吗?OP使用的是第三方库jPathWatcher吗?这种方法对我不适用。文件应该在应用程序之外添加/修改。那么我将如何编写metedata?在这种情况下,将这些元数据文件存储在应用程序的临时位置中。维护该元数据
文件中所有子文件夹的层次结构。这行吗?不过这个方法不是万无一失的。欢迎使用堆栈溢出!虽然这个代码片段可能是解决方案,但它确实有助于提高文章的质量。请记住,您将在将来回答读者的问题,这些人可能不知道您的代码建议的原因。
public class FolderWatcherHandler extends AbstractWatcher
{
@Override
public void eventDetected(Event event)
{
// Do stuff
}
}
try {
Path rootFolder = Paths.get(ctxProperties.getProperty("rootFolder"));
WatchService watcher = rootFolder.getFileSystem().newWatchService();
rootFolder.register(watcher, StandardWatchEventKinds.ENTRY_CREATE);
while (true) {
WatchKey watchKey = watcher.take();
if (watchKey != null) {
for (WatchEvent event : watchKey.pollEvents()) {
if (StandardWatchEventKinds.ENTRY_CREATE.equals(event.kind())) {
String fileName = rootFolder.toString() + "/" + event.context().toString();
String messageStr = convertFileToString(fileName);
if (messageStr != null) {
try {
sendMessage(jmsPublisher, messageStr, getJmsProperties());
moveMessageToProcessedDirectory(fileName, ctxProperties.getProperty("successFolder"), ".ok");
LOGGER.info("JMS message successfully sent");
sleep(Long.parseLong(ctxProperties.getProperty("sleepBetweenMsgMse")));
} catch (Exception e) {
moveMessageToProcessedDirectory(fileName, ctxProperties.getProperty("errorFolder"), ".nok");
}
} else {
LOGGER.error("ERROR: error parsing file content to string with file: " + fileName);
moveMessageToProcessedDirectory(fileName, ctxProperties.getProperty("errorFolder"), ".nok");
}
}
}
boolean valid = watchKey.reset();
if (!valid) {
LOGGER.error("ERROR: the watcher is no longer valid, the directory is inaccessible");
break;
}
} else {
LOGGER.error("ERROR: the watcher is null or not watchable");
break;
}
}
} catch (InterruptedException interruptedException) {
LOGGER.error("InterruptedException: thread got interrupted",interruptedException);
} catch (Exception exception) {
LOGGER.error("Exception: " + exception.getMessage(), exception);
}