File.createNewFile () creates files with the last modified time before the actual creation time
I am using JPoller to detect changes to files in a specific directory, but it is missing files because they end up timestamped earlier than their actual creation time. This is 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 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 this is what I get for the 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
This results in a race condition:
- JPoller records last check time as xyz ... 123
- File created in xyz ... 456
- The file with the last modified timestamp actually reads xyz ... 000
- JPoller looks for new / updated files with timestamp greater than xyz ... 123
- JPoller ignores the newly added file because xyz ... 000 is less than xyz ... 123
- I am pulling my hair out for a while.
I tried digging around in the code, but lastModified()
also createNewFile()
native calls end up being allowed, so I am left with little information.
For test.9
, I am wasting 957 milliseconds . What accuracy can I expect? Can my results vary depending on the operating system or file system? Suggested workarounds?
NOTE. I am currently running Linux with an XFS file system. I wrote a short program in C
, and the stat system call shows st_mtime
how truncate(xyz...000/1000)
.
UPDATE . I ran the same program as on Windows 7 with NTFS, andmaintains full millisecond precision. MSDN link @mdma provided additional notes that FAT filesystems are accurate to create at 10ms resolution, but only accessed with 2 seconds precision. So it really depends on the OS.
a source to share
File systems do not keep time accurately, and often do not have millisecond resolution, for example. FAT has 2 second permission for creation time, and NTFS can delay updating the last access time by up to an hour. (more on MSDN .) Although not in your case, in general, there is also a clock sync issue if the file is created on another computer.
It seems like it might be a problem for JPoller users as it is the timing logic. Until it gets fixed, you can get around this by manually adjusting the last modified time of each file, written to +4 seconds from the actual time - +4 is an arbitrary value that should be greater than the file system resolution over which you are working. When files are written to the file system, they will be rounded, but less than the value you added. Not really, but it will work!
a source to share