file.createNewFile() создает файлы с последним измененным временем до фактического времени создания

Я использую 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 миллисекунд. Какую точность я могу ожидать? Будут ли мои результаты различаться в зависимости от операционной системы или файловой системы? Предлагаемые обходные пути?

ПРИМЕЧАНИЕ. В настоящее время я использую Linux с файловой системой XFS. Я написал быструю программу в C и системный вызов stat показывает st_mtime как truncate(xyz...000/1000),

ОБНОВЛЕНИЕ: я запустил ту же программу, что и выше, на Windows 7 с NTFS, и она поддерживает точность до миллисекунд. Ссылка MSDN @mdma предоставила дополнительные примечания о том, что файловые системы FAT точны для создания с разрешением 10 мс, но для доступа - только до 2 секунд. Таким образом, это действительно зависит от ОС.

2 ответа

Решение

Файловые системы не хранят время точно и часто не с разрешением в миллисекунды, например, FAT имеет 2-секундное разрешение для времени создания, а NTFS может отложить обновление времени последнего доступа на срок до часа. (подробности о MSDN.) Хотя в вашем случае это не так, в общем, существует проблема синхронизации часов, если файл создается на другом компьютере.

Кажется, это может быть проблемой для людей JPoller, так как именно в этом и заключается логика обработки времени. Пока это не исправлено, вы можете обойти это, вручную установив время последнего изменения каждого записанного файла равным +4 секундам от фактического времени - +4 - это произвольное значение, которое должно быть больше, чем разрешение файловой системы, с которой вы работаете. Когда файлы записываются в файловую систему, они округляются в меньшую сторону, но на величину, меньшую добавленного вами значения. Не красиво, но это будет работать!

Последняя измененная временная метка, очевидно, сохраняется в секундах, а не в миллисекундах. Это может быть ограничение файловой системы. Я бы предложил сравнить его с секундами, а не с миллисекундами.

Другие вопросы по тегам