file.createNewFile() creates files with last-modified time before actual creation time

Posted by Kaleb Pederson on Stack Overflow See other posts from Stack Overflow or by Kaleb Pederson
Published on 2010-04-27T00:26:02Z Indexed on 2010/04/27 0:53 UTC
Read the original article Hit count: 369

I'm using JPoller to detect changes to files in a specific directory, but it's missing files because they end up with a timestamp earlier than their actual creation time. Here's how I test:

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");
        }
    }
}

And here's what I get for output:

-----------------------------------------
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

The result is a race condition:

  1. JPoller records time of last check as xyz...123
  2. File created at xyz...456
  3. File last-modified timestamp actually reads xyz...000
  4. JPoller looks for new/updated files with timestamp greater than xyz...123
  5. JPoller ignores newly added file because xyz...000 is less than xyz...123
  6. I pull my hair out for a while

I tried digging into the code but both lastModified() and createNewFile() eventually resolve to native calls so I'm left with little information.

For test.9, I lose 957 milliseconds. What kind of accuracy can I expect? Are my results going to vary by operating system or file system? Suggested workarounds?

NOTE: I'm currently running Linux with an XFS filesystem. I wrote a quick program in C and the stat system call shows st_mtime as truncate(xyz...000/1000).

© Stack Overflow or respective owner

Related posts about java

Related posts about os-dependent