我有一组源文件夹。我使用Java类从这些文件夹中构建分发文件。我想在Java中编写另一个每半秒运行一次的小类,检查文件夹中的任何文件是否已更改,如果是,请运行building类。在Java中跟踪文件夹更改的最简单方法是什么?
那么,如何轻松检测到文件夹已被修改?
我有一组源文件夹。我使用Java类从这些文件夹中构建分发文件。我想在Java中编写另一个每半秒运行一次的小类,检查文件夹中的任何文件是否已更改,如果是,请运行building类。在Java中跟踪文件夹更改的最简单方法是什么?
那么,如何轻松检测到文件夹已被修改?
我认为您需要检查目录和子目录修改时间(用于添加/删除文件)和文件修改时间(用于每个文件中的更改)。
编写一个递归例程,检查目录的修改时间以及是否更改了每个文件。然后检查目录内容,并递归调用任何子目录。您应该能够检查比上次运行检查时更多的修改时间。
编辑:由于我写上面,Java 7的推出了其directory watching capability。
如果你
可以使用Java 7,它支持平台无关的目录/文件更改通知。
JNA有一个跨平台变更通知示例here。不知道你有多容易找到它。
我不知道它是否有好处,但here's一个人的问题。
听起来像.NET有一些内置:FileSystemWatcher
UPDATE:感谢kd304,我刚刚得知的Java 7将有same feature。今天不会有太大的好处,除非你可以使用preview release。
与NIO2(Java7)它会很容易。使用Java6,你可以调用list(),并且每秒一次与之前的列表进行比较? (一个可怜的人注视着服务)
您需要手表每个文件和跟踪File.lastModified
属性和一个有点简单递归走的目录结构一起检查File.exists
标志。
这里列出possible solutions和一个简单File/Folder Watcher的例子。
是的,目录有很多可用的侦听器,但它们都相对复杂,并且大部分涉及线程。
几天前,我和一位工程师讨论了是否允许允许创建一个新的线程(在Web应用程序中)来监视目录树。最后,我同意他的观点,但是凭借提出如此之快的东西以至于不需要有听众。注意:下面描述的解决方案仅适用于您不需要知道哪个文件已更改,只有和文件已更改。
您提供以下方法与文件集合(例如,,通过Apache IO的FileUtils.listFiles()方法获得),并返回集合的哈希值。如果任何文件被添加,删除或其修改日期改变,哈希将改变。
在我的测试中,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();
}
是的,还有改进的空间(例如,我们使用散列法而不是内联)。以上是从我们的实际代码中删除,但应该给你一个好主意我们做了什么。