代码之家  ›  专栏  ›  技术社区  ›  Kaleb Pederson

file.createNewFile()使用实际创建时间之前的上次修改时间创建文件

  •  2
  • Kaleb Pederson  · 技术社区  · 16 年前

    我在用 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。我写了一个快速程序 C 以及 stat system call 显示 st_mtime 作为 truncate(xyz...000/1000) .

    更新 :我在windows 7上运行了与上面相同的ntfs程序 保持全毫秒精度。这个 MSDN link @mdma进一步指出,fat文件系统对于分辨率为10ms的creates来说是准确的,但是对于access来说只有2秒。因此,这是真正的操作系统依赖。

    2 回复  |  直到 16 年前
        1
  •  2
  •   mdma    16 年前

    文件系统不精确地存储时间,而且通常不以毫秒级的分辨率存储,例如,fat对于创建时间的分辨率为2秒,而ntfs可以将上次访问时间的更新延迟一个小时。(详情) MSDN )虽然不是在您的情况下,但通常,如果文件是在另一台计算机上创建的,则也存在同步时钟的问题。

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

        2
  •  2
  •   BalusC    16 年前

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