I have a set of source folders. I use a Java class to build the distribution file out of these folders. I'd like to write another little class in Java which runs every half a second, checks if any of the files in the folders have changed, and if yes, run the building class.
我有一组源文件夹。我使用Java类从这些文件夹中构建分发文件。我想在Java中编写另一个小类,每半秒运行一次,检查文件夹中的任何文件是否已更改,如果是,则运行构建类。
So, how do I detect easily that a folder has been modified ?
那么,如何轻松检测到文件夹已被修改?
7 个解决方案
#1
I think you will need to check the directory and subdirectory modfication times (for files being added/removed) and the file modification times (for the changes in each file).
我认为您需要检查目录和子目录修改时间(对于要添加/删除的文件)和文件修改时间(对于每个文件中的更改)。
Write a recursive routine that checks a directory for it's modification time and if it's changed, plus each files. Then checks the directory contents, and call recursively for any subdirectories. You should just be able to check for any modification times greater than when you last ran the check.
编写一个递归例程,检查目录是否有修改时间,是否已更改,以及每个文件。然后检查目录内容,并递归调用任何子目录。您应该能够检查比上次运行检查时更大的修改时间。
EDIT: Since I wrote the above, Java 7 came out with its directory watching capability.
编辑:自从我上面写了以后,Java 7出现了它的目录监视功能。
#2
Here a list of possible solutions and an example of simple File/Folder Watcher.
这里列出了可能的解决方案和简单文件/文件夹观察器的示例。
#3
If you
can
are allowed to use Java 7, it has support for platform independent directory/file change notifications.
如果您可以使用Java 7,则它支持与平台无关的目录/文件更改通知。
JNA has a sample for cross platform change notification here. Not sure how easy you might find it.
JNA在此提供了跨平台变更通知的示例。不确定你会发现它有多容易。
#4
I don't know if it's any good, but here's one person's take on the problem.
我不知道它是否有任何好处,但这是一个人对这个问题的看法。
Sounds like .NET has something built-in: FileSystemWatcher
听起来像.NET内置了一些东西:FileSystemWatcher
UPDATE: Thanks to kd304, I just learned that Java 7 will have the same feature. Won't do you much good today, unless you can use the preview release.
更新:感谢kd304,我刚刚了解到Java 7将具有相同的功能。除非您可以使用预览版,否则今天对您没有太大帮助。
#5
You need to watch each file and keep track of the File.lastModified
attribute and check the File.exists
flag together with a bit of simple recursion to walk the directory structure.
您需要观察每个文件并跟踪File.lastModified属性并检查File.exists标志以及一些简单的递归来遍历目录结构。
#6
with NIO2 (Java7) it will be very easy. With Java6 you could call list() and compare with previous list once a second? (a poor man watching service)
使用NIO2(Java7)将非常容易。使用Java6,您可以调用list()并与之前的列表进行一次比较吗? (一个穷人看服务)
#7
Yes, there are a number of available listeners for directories, but they're all relatively complicated and most involve threads.
是的,目录中有许多可用的侦听器,但它们都相对复杂,而且大多数涉及线程。
A few days ago I ended up in an almost heated discussion with one of our engineers over whether it was a permissible creating a new thread (in a web application) simply to monitor a directory tree. In the end I agreed with him, but by virtue of coming up with something so fast that having a listener is unnecessary. Note: the solution described below only works if you don't need to know which file has changed, only that a file has changed.
几天前,我与我们的一位工程师进行了几乎激烈的讨论,讨论是否允许创建一个新的线程(在Web应用程序中)来监视目录树。最后我和他达成了一致,但是由于提出了一些如此之快的事情,以至于不需要听众。注意:下面描述的解决方案仅在您不需要知道哪个文件已更改,只知道文件已更改时才有效。
You provide the following method with a Collection of Files (e.g., obtained via Apache IO's FileUtils.listFiles() method) and this returns a hash for the collection. If any file is added, deleted, or its modification date changed, the hash will change.
您使用文件集合提供以下方法(例如,通过Apache IO的FileUtils.listFiles()方法获得),这将返回集合的哈希值。如果添加,删除任何文件或更改其修改日期,则哈希将更改。
In my tests, 50K files takes about 750ms on a 3Ghz Linux box. Touching any of the files alters the hash. In my own implementation I'm using a different hash algorithm (DJB) that's a bit faster but that's the gist of it. We now just store the hash and check each time as it's pretty painless, especially for smaller file collections. If anything changes we then re-index the directory. The complexity of a watcher just wasn't worth it in our application.
在我的测试中,在3Ghz Linux机器上,50K文件大约需要750毫秒。触摸任何文件都会改变哈希值。在我自己的实现中,我使用的是另一种哈希算法(DJB),但速度要快一些,但这就是它的要点。我们现在只是存储哈希值,并且每次检查它都非常轻松,特别是对于较小的文件集合。如果有任何变化,我们会重新索引目录。观察者的复杂性在我们的应用程序中是不值得的。
/**
* Provided a directory and a file extension, returns
* a hash using the Adler hash algorithm.
*
* @param files the Collection of Files to hash.
* @return a hash of the Collection.
*/
public static long getHash( Collection<File> files )
{
Adler32 adler = new Adler32();
StringBuilder sb = new StringBuilder();
for ( File f : files ) {
String s = f.getParent()+'/'+f.getName()+':'+String.valueOf(f.lastModified());
adler.reset();
adler.update(s.getBytes());
sb.append(adler.getValue()+' ');
}
adler.reset();
adler.update(sb.toString().getBytes());
return adler.getValue();
}
And yes, there's room for improvement (e.g., we use a hash method rather than inlining it). The above is cut down from our actual code but should give you a good idea what we did.
是的,还有改进的余地(例如,我们使用哈希方法而不是内联方法)。以上内容是从我们的实际代码中删除的,但应该让您知道我们做了什么。
#1
I think you will need to check the directory and subdirectory modfication times (for files being added/removed) and the file modification times (for the changes in each file).
我认为您需要检查目录和子目录修改时间(对于要添加/删除的文件)和文件修改时间(对于每个文件中的更改)。
Write a recursive routine that checks a directory for it's modification time and if it's changed, plus each files. Then checks the directory contents, and call recursively for any subdirectories. You should just be able to check for any modification times greater than when you last ran the check.
编写一个递归例程,检查目录是否有修改时间,是否已更改,以及每个文件。然后检查目录内容,并递归调用任何子目录。您应该能够检查比上次运行检查时更大的修改时间。
EDIT: Since I wrote the above, Java 7 came out with its directory watching capability.
编辑:自从我上面写了以后,Java 7出现了它的目录监视功能。
#2
Here a list of possible solutions and an example of simple File/Folder Watcher.
这里列出了可能的解决方案和简单文件/文件夹观察器的示例。
#3
If you
can
are allowed to use Java 7, it has support for platform independent directory/file change notifications.
如果您可以使用Java 7,则它支持与平台无关的目录/文件更改通知。
JNA has a sample for cross platform change notification here. Not sure how easy you might find it.
JNA在此提供了跨平台变更通知的示例。不确定你会发现它有多容易。
#4
I don't know if it's any good, but here's one person's take on the problem.
我不知道它是否有任何好处,但这是一个人对这个问题的看法。
Sounds like .NET has something built-in: FileSystemWatcher
听起来像.NET内置了一些东西:FileSystemWatcher
UPDATE: Thanks to kd304, I just learned that Java 7 will have the same feature. Won't do you much good today, unless you can use the preview release.
更新:感谢kd304,我刚刚了解到Java 7将具有相同的功能。除非您可以使用预览版,否则今天对您没有太大帮助。
#5
You need to watch each file and keep track of the File.lastModified
attribute and check the File.exists
flag together with a bit of simple recursion to walk the directory structure.
您需要观察每个文件并跟踪File.lastModified属性并检查File.exists标志以及一些简单的递归来遍历目录结构。
#6
with NIO2 (Java7) it will be very easy. With Java6 you could call list() and compare with previous list once a second? (a poor man watching service)
使用NIO2(Java7)将非常容易。使用Java6,您可以调用list()并与之前的列表进行一次比较吗? (一个穷人看服务)
#7
Yes, there are a number of available listeners for directories, but they're all relatively complicated and most involve threads.
是的,目录中有许多可用的侦听器,但它们都相对复杂,而且大多数涉及线程。
A few days ago I ended up in an almost heated discussion with one of our engineers over whether it was a permissible creating a new thread (in a web application) simply to monitor a directory tree. In the end I agreed with him, but by virtue of coming up with something so fast that having a listener is unnecessary. Note: the solution described below only works if you don't need to know which file has changed, only that a file has changed.
几天前,我与我们的一位工程师进行了几乎激烈的讨论,讨论是否允许创建一个新的线程(在Web应用程序中)来监视目录树。最后我和他达成了一致,但是由于提出了一些如此之快的事情,以至于不需要听众。注意:下面描述的解决方案仅在您不需要知道哪个文件已更改,只知道文件已更改时才有效。
You provide the following method with a Collection of Files (e.g., obtained via Apache IO's FileUtils.listFiles() method) and this returns a hash for the collection. If any file is added, deleted, or its modification date changed, the hash will change.
您使用文件集合提供以下方法(例如,通过Apache IO的FileUtils.listFiles()方法获得),这将返回集合的哈希值。如果添加,删除任何文件或更改其修改日期,则哈希将更改。
In my tests, 50K files takes about 750ms on a 3Ghz Linux box. Touching any of the files alters the hash. In my own implementation I'm using a different hash algorithm (DJB) that's a bit faster but that's the gist of it. We now just store the hash and check each time as it's pretty painless, especially for smaller file collections. If anything changes we then re-index the directory. The complexity of a watcher just wasn't worth it in our application.
在我的测试中,在3Ghz Linux机器上,50K文件大约需要750毫秒。触摸任何文件都会改变哈希值。在我自己的实现中,我使用的是另一种哈希算法(DJB),但速度要快一些,但这就是它的要点。我们现在只是存储哈希值,并且每次检查它都非常轻松,特别是对于较小的文件集合。如果有任何变化,我们会重新索引目录。观察者的复杂性在我们的应用程序中是不值得的。
/**
* Provided a directory and a file extension, returns
* a hash using the Adler hash algorithm.
*
* @param files the Collection of Files to hash.
* @return a hash of the Collection.
*/
public static long getHash( Collection<File> files )
{
Adler32 adler = new Adler32();
StringBuilder sb = new StringBuilder();
for ( File f : files ) {
String s = f.getParent()+'/'+f.getName()+':'+String.valueOf(f.lastModified());
adler.reset();
adler.update(s.getBytes());
sb.append(adler.getValue()+' ');
}
adler.reset();
adler.update(sb.toString().getBytes());
return adler.getValue();
}
And yes, there's room for improvement (e.g., we use a hash method rather than inlining it). The above is cut down from our actual code but should give you a good idea what we did.
是的,还有改进的余地(例如,我们使用哈希方法而不是内联方法)。以上内容是从我们的实际代码中删除的,但应该让您知道我们做了什么。