Java - 文件lastModified和读取文件的区别

3
我正在使用文件并需要在Java中更新值,当文件被修改时。因此,我考虑使用File类的lastModified来检查修改时间,并且如果已修改则从文件中读取并更新单个属性。
我的疑惑是,lastModified是否像读取单个属性/整个文件一样耗费大量资源。因为我的测试结果显示几乎相同的结果。所以,在长期运行中,每次读取文件并从文件中更新属性是否比检查lastModified更好呢?
注意:此操作每分钟执行一次。
还是有比轮询lastModified更好的选项来检查文件是否已更改?我正在使用Java 6。
2个回答

5
由于您使用的是Java 6,检查修改日期或文件内容是您的唯一选择(有另一个答案讨论了使用更新的java.nio.file功能,如果您有升级到Java 7的选项,那么您应该认真考虑)。
回答您最初的问题:
您没有指定文件的位置(即它是在本地磁盘上还是在其他地方的服务器上),我会假定它在本地磁盘上,但如果文件在不同的机器上,网络延迟和 netbios/dfs/无论您使用的任何网络文件系统都将加剧差异。
检查文件的修改日期涉及从磁盘读取元数据。检查文件内容需要从磁盘读取文件内容(如果文件很小,则只需进行一次读取操作。如果文件较大,则可能需要多次读取操作)。
阅读文件内容可能涉及读写锁检查。通常来说,检查文件的修改日期不需要读写锁检查(根据文件系统,元数据磁盘页面上仍然可能发生一些一致性锁定,但这些锁相对于文件锁更轻量级)。
如果文件经常更改(即您实际上期望每分钟更改一次),则检查修改日期只是开销 - 在大多数情况下,您将读取文件内容。如果文件不经常更改,则修改日期检查肯定有优势,如果文件很大(您必须读取整个文件才能获得信息)。
如果文件很小且不经常更改,则这几乎是相同的。在大多数情况下,文件内容和文件元数据已经被分页到RAM中 - 因此两个操作都是相对高效的RAM内容检查。
我个人会进行修改日期检查,因为它在逻辑上是有意义的(并且如果文件大小超过一个磁盘页面,它还可以保护您免受性能影响) - 但如果文件经常更改,则我会直接读取文件内容。但是,无论哪种方式都没有问题。
这就带来了我们的自发建议:我猜想,这个操作的性能在整个事情的重要性方面并不重要。即使它比现在慢1000倍,它可能仍然不会影响应用程序的主要目的/性能。因此,我的真正建议是编写代码并继续前进-除非这成为应用程序的瓶颈,否则不要担心其性能。

4
引用自JAVA教程
为实现文件更改通知(file change notification)功能,程序必须能够检测到文件系统上相关目录的变化。一种方法是轮询文件系统以查找变化,但这种方法效率低下,不适用于需要监视数百个打开文件或目录的应用程序。
java.nio.file包提供了一个文件更改通知API,称为Watch Service API。该API允许您使用监视服务注册一个目录(或多个目录)。在注册时,您告诉服务您感兴趣的事件类型:文件创建、文件删除或文件修改。当服务检测到感兴趣的事件时,将其转发到已注册的进程。已注册的进程有一个专门用于监视其注册的任何事件的线程(或线程池)。当事件到达时,按需要进行处理。
以下链接提供了一些实现此服务示例源代码: 链接1 链接2 编辑:感谢Kevin Day在评论中指出,由于您正在使用Java 6,因此此方法可能不起作用。尽管在Apache Commons IO中提供了替代方法,但我没有使用过,所以您需要自行检查 :)

哦,是的,我错过了那个。我曾经使用过这个东西,它非常好用,只需要修改Java提供的代码中的目录路径和监控参数即可。不断轮询文件系统并检查最后修改时间似乎有点琐碎。有一种替代方法是使用ORG.APACHE.COMMONS IO类,但我还没有使用过它们。我会在编辑中提到它们,谢谢 :) - Mustafa sabir
我还没有检查过代码,但我的猜测是org.apache.commons.io在Java 6下会退回到轮询。除非apache部署了本地库(不太可能),否则无法钩入文件系统通知系统...使用像commons.io这样的库的好处是它很好地封装了轮询-但实际上,这种东西只需要3或4行代码,而且很容易实现即席。 - Kevin Day

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接