2

我正在使用JPoller来检测对特定目录中文件的更改,但它丢失了文件,因为它们最终的时间戳早于它们的实际创建时间。这是我的测试方式:

public static void main(String [] files)
{
    for (String file : files)
    {
        File f = new File(file);
        if (f.exists())
        {
            System.err.println(file + " exists");
            continue;
        }

        try
        {
            // find out the current time, I would hope to assume that the last-modified
            // time on the file will definitely be later than this
            System.out.println("-----------------------------------------");
            long time = System.currentTimeMillis();

            // create the file
            System.out.println("Creating " + file + " at " + time);
            f.createNewFile();

            // let's see what the timestamp actually is (I've only seen it <time)
            System.out.println(file + " was last modified at: " + f.lastModified());

            // well, ok, what if I explicitly set it to time?
            f.setLastModified(time);
            System.out.println("Updated modified time on " + file + " to " + time + " with actual " + f.lastModified());
        }
        catch (IOException e)
        {
            System.err.println("Unable to create file");
        }
    }
}

这就是我得到的输出:

-----------------------------------------
Creating test.7 at 1272324597956
test.7 was last modified at: 1272324597000
Updated modified time on test.7 to 1272324597956 with actual 1272324597000
-----------------------------------------
Creating test.8 at 1272324597957
test.8 was last modified at: 1272324597000
Updated modified time on test.8 to 1272324597957 with actual 1272324597000
-----------------------------------------
Creating test.9 at 1272324597957
test.9 was last modified at: 1272324597000
Updated modified time on test.9 to 1272324597957 with actual 1272324597000

结果是一个竞争条件:

  1. JPoller 将上次检查的时间记录为 xyz...123
  2. 在 xyz...456 创建的文件
  3. 文件最后修改的时间戳实际上读取 xyz...000
  4. JPoller 查找时间戳大于 xyz...123 的新/更新文件
  5. JPoller 忽略新添加的文件,因为 xyz...000 小于 xyz...123
  6. 我把头发拉了一会儿

我尝试深入研究代码,但最终都lastModified()解决createNewFile()了本机调用,所以我只剩下很少的信息了。

因为test.9我损失了 957 毫秒。我可以期待什么样的准确性?我的结果会因操作系统或文件系统而异吗?建议的解决方法?

注意:我目前正在使用 XFS 文件系统运行 Linux。我在其中编写了一个快速程序,Cstat系统调用显示st_mtimetruncate(xyz...000/1000).

更新:我在带有 NTFS 的 Windows 7 上运行了与上面相同的程序,它确实保持了完整的毫秒精度。MSDN 链接@mdma 提供了进一步的说明,FAT 文件系统对于分辨率为 10 毫秒的创建是准确的,但对于访问仅准确到 2 秒。因此,这确实取决于操作系统。

4

2 回答 2

2

最后修改的时间戳显然是以秒为单位存储的,而不是以毫秒为单位的。这可能是文件系统限制。我建议将它与秒而不是毫秒进行比较。

于 2010-04-27T00:51:05.610 回答
2

文件系统不能精确地存储时间,而且通常不是毫秒分辨率,例如 FAT 的创建时间分辨率为 2 秒,而 NTFS 可以延迟更新最后一次访问时间长达一个小时。(MSDN上的详细信息。)虽然不是你的情况,但一般来说,如果文件是在另一台计算机上创建的,也会存在同步时钟的问题。

对于 JPoller 人来说,这似乎是一个问题,因为这是时间处理逻辑所在。在修复之前,您可以通过手动将每个写入文件的最后修改时间设置为与实际时间相差 +4 秒来解决此问题 - +4 是一个任意值,应该大于您正在处理的文件系统的分辨率。当文件写入文件系统时,它们将被四舍五入,但小于您添加的值。不漂亮,但它会工作!

于 2010-04-27T02:20:53.353 回答